每日20道面试题带解析 05

web前端开发

共 10725字,需浏览 22分钟

 ·

2021-06-03 14:16

以下题目,本人验证无误,查阅了相关资料,得出解析部分并做了相关总结,希望对正准备跳槽或找工作的你有帮助!

1、怎样才能在 index.js 中调用 sum.js? 中的 sum?

// sum.jsexport default function sum(x) {  return x + x;}
// index.jsimport * as sum from "./sum";
  • A: sum(4)

  • B: sum.sum(4)

  • C: sum.default(4)

  • D: 默认导出不用 * 来导入,只能具名导出

答案及解析

答案 : C解析 : 相当于以下形式引入值 sum:{ default: function sum(x) { return x + x } }    通过调用 sum.default 来调用该函数

2、以下哪一项会对对象 person 有副作用?

const person = { name: "Lydia Hallie" };
Object.seal(person);
  • A: person.name = "Evan Bacon"

  • B: person.age = 21

  • C: delete person.name

  • D: Object.assign(person, { age: 21 })

答案及解析

答案 : A解析 : Object.seal 可以防止新属性 被添加,或者存在属性被移除.然而,你仍然可以对存在属性进行更改。

3、以下哪一项会对对象 person 有副作用?

const person = {  name: "Lydia Hallie",  address: {    street: "100 Main St"  }};
Object.freeze(person);
  • A: person.name = "Evan Bacon"

  • B: delete person.address

  • C: person.address.street = "101 Main St"

  • D: person.pet = { name: "Mara" }


答案及解析


答案 : C解析 : Object.freeze 对一个对象进行 冻结。不能对属性进行添加,修改,删除。 然而仅对 对象进行 浅 冻结,意味着只有 对象中的 直接 属性被冻结。 如果属性是另一个 object,像案例中的 address,address 中的属性没有被冻结,仍然可以被修改

4、 写出执行结果,并解释原因

class Bird {  constructor() {    console.log("I'm a bird. 🦢");  }}
class Flamingo extends Bird { constructor() { console.log("I'm pink. 🌸"); super(); }}
const pet = new Flamingo();
  • A: I'm pink. 🌸

  • B: I'm pink. 🌸 I'm a bird. 🦢

  • C: I'm a bird. 🦢 I'm pink. 🌸

  • D: Nothing, we didn't call any method


答案及解析

答案 : B解析 : 创建了类 Flamingo 的实例 pet。实例化这个实例时Flamingo 中的 constructor 被调用。   首先,输出 "I'm pink. 🌸", 随后调用super()。super() 调用父类的构造函数Bird。   Bird 的构造函数被调用,并输出 "I'm a bird. 🦢"。

5、哪一个选项会导致报错?

const emojis = ["🎄", "🎅🏼", "🎁", "⭐"];
/* 1 */ emojis.push("🦌");/* 2 */ emojis.splice(0, 2);/* 3 */ emojis = [...emojis, "🥂"];/* 4 */ emojis.length = 0;
  • A: 1

  • B: 1 and 2

  • C: 3 and 4

  • D: 3


答案及解析


答案 : D解析 : const 声明的变量不能 重定义 变量的值,仅可读。 但数组中的值可被修改,如 push 新的值, 拼接,又或者将数组的长度设置为0。

6、输出什么?

const fruit = ['🍌', '🍊', '🍎']
fruit.slice(0, 1)fruit.splice(0, 1)fruit.unshift('🍇')
console.log(fruit)
  • A: ['🍌', '🍊', '🍎']

  • B: ['🍊', '🍎']

  • C: ['🍇', '🍊', '🍎']

  • D: ['🍇', '🍌', '🍊', '🍎']


答案及解析


答案 : C解析 : 1. slice方法不会改变原数组,返回从数组截取的值 2. splice方法会改变原数组,数组此时为 ['🍊', '🍎']。 3. unshift方法会改变原数组,第一个位置添加一个值,数组此时为 ['🍇', '🍊', '🍎']。

7、输出什么?

const getList = ([x, ...y]) => [x, y]const getUser = user => { name: user.name, age: user.age }
const list = [1, 2, 3, 4]const user = { name: "Lydia", age: 21 }
console.log(getList(list))console.log(getUser(user))
  • A: [1, [2, 3, 4]] and undefined

  • B: [1, [2, 3, 4]] and { name: "Lydia", age: 21 }

  • C: [1, 2, 3, 4] and { name: "Lydia", age: 21 }

  • D: Error and { name: "Lydia", age: 21 }


答案及解析


答案 : A解析 : 1. getList函数接收一个数组作为其参数。在getList函数的括号之间,立即解构这个数组。 [x, ...y] = [1, 2, 3, 4],剩余参数...y存放在一个数组中[2,3,4] 当打印[x,y]时,会打印[1,[2,3,4]]。 2. getUser函数接收一个对象。对于箭头函数,如果只返回一个值,不必编写花括号。 但是,如果返回一个对象,必须在圆括号之间编写它,否则不会返回任何值! 因此该函数返回undefined。 const getUser = user => ({ name: user.name, age: user.age }) // 可返回对象

8、 输出什么?

function getFine(speed, amount) {  const formattedSpeed = new Intl.NumberFormat({    'en-US',    { style: 'unit', unit: 'mile-per-hour' }  }).format(speed)
const formattedAmount = new Intl.NumberFormat({ 'en-US', { style: 'currency', currency: 'USD' } }).format(amount)
return `The driver drove ${formattedSpeed} and has to pay ${formattedAmount}`}
console.log(getFine(130, 300))
  • A: The driver drove 130 and has to pay 300

  • B: The driver drove 130 mph and has to pay $300.00

  • C: The driver drove undefined and has to pay undefined

  • D: The driver drove 130.00 and has to pay 300.00


答案及解析

答案 : B解析 : Intl.NumberFormat 方法,可以格式化任意区域的数字值。      mile-per-hour 通过格式化结果为 mph; USD通过格式化结果为 $.

9、 如何能打印出console.log语句后注释掉的值?

function* startGame() {  const answer = yield "Do you love JavaScript?";  if (answer !== "Yes") {    return "Oh wow... Guess we're gone here";  }  return "JavaScript loves you back ❤️";}
const game = startGame();console.log(/* 1 */); // Do you love JavaScript?console.log(/* 2 */); // JavaScript loves you back ❤️
  • A: game.next("Yes").value and game.next().value

  • B: game.next.value("Yes") and game.next.value()

  • C: game.next().value and game.next("Yes").value

  • D: game.next.value() and game.next.value("Yes")


答案及解析

答案 : C解析 : generator函数在遇到yield关键字时会“暂停”其执行。  1. 首先让函数产生字符串`Do you love JavaScript?`,这可以通过调用 game.next().value 来完成。  2. yield 表达式本身没有返回值,或者说总是返回 undefined, 这意味着此时变量 answer 为 undefined  3. next 方法可以带一个参数,该参数会被当作上一个 yield 表达式的返回值。  4. 当调用 game.next("Yes").value 时,先前的 yield 的返回值将被替换为next()函数的参数"Yes"。  5. 此时变量 answer 被赋值为 "Yes",if语句返回false,所以`JavaScript loves you back ❤️`被打印。

10、输出什么?

async function getData() {  return await Promise.resolve("I made it!");}
const data = getData();console.log(data);
  • A: "I made it!"

  • B: Promise {<resolved>: "I made it!"}

  • C: Promise {<pending>}

  • D: undefined


答案及解析


答案 : C解析 : 异步函数始终返回一个promise。await 仍然需要等待promise的解决:当我们调用getData()并将其赋值给data,此时 data 为 getData 方法返回的一个挂起的 promise,该promise并没有解决。如果想要访问已解决的值"I made it!",可以在 data 上使用 .then() 方法:data.then(res => console.log(res)) // "I made it!"

11、输出什么?

class Counter {  #number = 10
increment() { this.#number++ }
getNum() { return this.#number }}
const counter = new Counter()counter.increment()
console.log(counter.#number)
  • A: 10

  • B: 11

  • C: undefined

  • D: SyntaxError


答案及解析

答案 : D解析 :ES2020 中,可以通过 # 给 class 添加私有变量。在 class 的外部无法获取该值。当尝试输出 counter.#number,语法错误被抛出:Uncaught SyntaxError: Private field '#number' must be declared in an enclosing class

12、 输出什么?

const teams = [  { name: "Team 1", members: ["Paul", "Lisa"] },  { name: "Team 2", members: ["Laura", "Tim"] }];
function* getMembers(members) { for (let i = 0; i < members.length; i++) { yield members[i]; }}
function* getTeams(teams) { for (let i = 0; i < teams.length; i++) { // TODO: ✨ SOMETHING IS MISSING HERE ✨ }}
const obj = getTeams(teams);obj.next(); // { value: "Paul", done: false }obj.next(); // { value: "Lisa", done: false }
  • A: yield getMembers(teams[i].members)

  • B: yield* getMembers(teams[i].members)

  • C: return getMembers(teams[i].members)

  • D: return yield getMembers(teams[i].members)


答案及解析

答案 : B解析 : 为了遍历 teams数组中每一项 members属性中的每一项,需要将 teams[i].members 传递给getMembers函数。Generator 函数返回一个 generator 对象。为了遍历这个 generator 对象中的每一项,需要使用 yield*.

13、输出什么?

const config = {  languages: [],  set language(lang) {    return this.languages.push(lang);  }};
console.log(config.language);
  • A: function language(lang) { this.languages.push(lang }

  • B: 0

  • C: []

  • D: undefined


答案及解析

答案 :  D解析 : 方法 language 是一个 setter。Setters 并不保存一个实际值,它们的使命在于 _修改_ 属性。当调用方法 setter, 返回 undefined。

14、输出什么?

function giveLydiaPizza() {  return "Here is pizza!"}
const giveLydiaChocolate = () => "Here's chocolate... now go hit the gym already."
console.log(giveLydiaPizza.prototype)console.log(giveLydiaChocolate.prototype)
  • A: { constructor: ...} { constructor: ...}

  • B: {} { constructor: ...}

  • C: { constructor: ...} {}

  • D: { constructor: ...} undefined


答案及解析


答案 : D解析 : giveLydiaPizza函数,有一个prototype属性,是一个带有constructor属性的对象(原型对象)。然而,箭头函数giveLydiaChocolate,没有prototype属性。访问prototype属性时会返回undefined。

15、写出执行结果,并解释原因

const info = {  [Symbol('a')]: 'b'}console.log(info)console.log(Object.keys(info))
  • A: {Symbol('a'): 'b'} and ["{Symbol('a')"]

  • B: {} and []

  • C: { a: "b" } and ["a"]

  • D: {Symbol('a'): 'b'} and []


答案及解析

答案 : D解析 : 关键点在于:Symbol类型是不可枚举的。1. 记录整个对象时,所有属性都是可见的,甚至是不可枚举的属性。2. Object.keys 方法返回对象上的所有可枚举的键属性。因此返回一个空数组。

16、 写出执行结果,并解释原因

function greeting() {  throw "Hello world!";}
function sayHi() { try { const data = greeting(); console.log("It worked!", data); } catch (e) { console.log("Oh no an error:", e); }}

答案及解析


答案 : 'Oh an error: Hello world'解析 : 通过throw语句,可以创建自定义错误。可以抛出异常。异常可以是字符串, 数字, 布尔类型 或者是一个对象。在本例中,异常是字符串'Hello world'.catch语句,可以捕获异常并作出相应处理。最终结果就是'Oh an error: Hello world'.

17、 写出执行结果,并解释原因

const handler = {  set: () => console.log("Added a new property!"),  get: () => console.log("Accessed a property!")};
const person = new Proxy({}, handler);
person.name = "Lydia";
答案及解析

答案 : Added a new property!, Accessed a property!解析 : 使用 Proxy 对象可以给一个对象添加自定义行为,传递一个包含以下属性的对象 handler : set and get。_设置_属性值时 set 被调用, _获取_属性值时 get 被调用。第一个参数是一个空对象 `{}`,作为 `person` 的值。对于这个对象,自定义行为被定义在对象 `handler`。如果我们向对象 `person` 添加属性,`set` 将被调用。如果我们获取 `person` 的属性, `get` 将被调用。首先,我们向 proxy 对象(`person.name = "Lydia"`)添加一个属性 `name`。`set` 被调用并输出 `"Added a new property!"`。然后,我们获取 proxy 对象的一个属性,对象 handler 的属性 `get` 被调用。输出 `"Accessed a property!"`。

18、 输出什么?

function* generator(i) {  yield i;  yield i * 2;}
const gen = generator(10);
console.log(gen.next().value);console.log(gen.next().value);

答案及解析

答案 : 10, 20解析 : 一般的函数在执行过程中不能暂停。但生成器函数却可以中途“停下”,之后可以再从停下的地方继续。生成器遇到yield关键字时,会生成yield后面的值。使用next()方法一步步执行生成器。

19、 输出什么?

function* generatorOne() {  yield ['a', 'b', 'c'];}
function* generatorTwo() { yield* ['a', 'b', 'c'];}
const one = generatorOne()const two = generatorTwo()
console.log(one.next().value)
答案及解析
答案 : ['a''b''c'] , a解析 : 通过 yield* 关键字, 可以在一个 Generator 函数里面执行另一个 Generator 函数, 或可遍历的对象 (如数组).在函数 generatorOne 中, yield ['a', 'b', 'c']。而one.next().value 等价于数组 ['a', 'b', 'c']        console.log(one.next().value) // ['a', 'b', 'c']        console.log(one.next().value) // undefined在函数 generatorTwo 中, yield* ['a', 'b', 'c'], 等价于在迭代器中第一个 yield 的值。就是 a, 所以two.next().value 返回 a。        console.log(two.next().value) // 'a'        console.log(two.next().value) // 'b'        console.log(two.next().value) // 'c'        console.log(two.next().value) // undefined

20、解释下段代码的意思以及用到的技术

[].forEach.call($$("*"),function(a){    a.style.outline="1px solid #"+(~~(Math.random()*(1<<24))).toString(16
答案及解析
答案与解析直观操作:获取页面所有的元素,使用随机色给这些元素加上1px的外边框用到的技术:  1. 选择页面中所有的元素:$$函数  $$函数是现代浏览器提供的一个命令行API,相当于document.querySelectorAll,可以将当前页面中的CSS选择器作为参数传给该方法,然后它会返回匹配的所有元素。  2. 遍历元素:[].forEach.call( $$('*'), function( a ) { ... });    call和apply方法,可以实现在类数组对象上调用数组方法。  3. 为元素添加外边框: a.style.outline="1px solid #" + color    使用outline属性给元素添加一个边框。由于渲染的outline不在CSS盒模型中,所以为元素添加outline并不会影响元素的大小和页面的布局。  4. 生成随机颜色: ~~(Math.random()*(1<<24))).toString(16)    - Math.random()*(1<<24) 可以得到 0~2^24 - 1 之间的随机数,使用了位操作  - 得到一个浮点数,连续使用两次取反操作符 ~ 获得整数部分,相当于使用parseInt            const a =12.34;            ~~a == parseInt(a, 10);   // true    - 使用toString(16)转换为一个十六进制的字符串。该方法将数值转换成字符串时,接收一个参数用以指明数值的进制。如果省略该参数,则默认采用十进制,可以为其指定进制,

本文完~



学习更多技能

请点击下方公众号


浏览 24
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报