avatar

面试题

记录一些看过的而且答错了的面试题

1
2
3
4
5
6
7
8
9
10
const shape = {
radius: 10,
diameter() {
return this.radius * 2
},
perimeter: () => 2 * Math.PI * this.radius
}

shape.diameter()
shape.perimeter()

注意 diameter 的值是一个常规函数,但是 perimeter 的值是一个箭头函数。

对于箭头函数,this 关键字指向的是它当前周围作用域(简单来说是包含箭头函数的常规函数,如果没有常规函数的话就是全局对象),这个行为和常规函数不同。这意味着当我们调用 perimeter 时,this 不是指向 shape 对象,而是它的周围作用域(在例子中是 window)。

在 window 中没有 radius 这个属性,因此返回 undefined。


1
2
3
4
5
6
7
8
9
10
11
12
13
class Chameleon {
static colorChange(newColor) {
this.newColor = newColor
return this.newColor
}

constructor({ newColor = 'green' } = {}) {
this.newColor = newColor
}
}

const freddie = new Chameleon({ newColor: 'purple' })
freddie.colorChange('orange')

colorChange 是一个静态方法。静态方法被设计为只能被创建它们的构造器使用(也就是 Chameleon),并且不能传递给实例。因为 freddie 是一个实例,静态方法不能被实例使用,因此抛出了 TypeError 错误。


1
2
3
4
5
6
7
8
9
10
11
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}

const member = new Person("Lydia", "Hallie");
Person.getFullName = function () {
return `${this.firstName} ${this.lastName}`;
}

console.log(member.getFullName());

你不能像常规对象那样,给构造函数添加属性。如果你想一次性给所有实例添加特性,你应该使用原型。因此本例中,使用如下方式:

1
2
3
Person.prototype.getFullName = function () {
return `${this.firstName} ${this.lastName}`;
}

这才会使 member.getFullName() 起作用。为什么这么做有益的?假设我们将这个方法添加到构造函数本身里。也许不是每个 Person 实例都需要这个方法。这将浪费大量内存空间,因为它们仍然具有该属性,这将占用每个实例的内存空间。相反,如果我们只将它添加到原型中,那么它只存在于内存中的一个位置,但是所有实例都可以访问它!


事件冒泡的三个阶段是什么? A: Target > Capturing > Bubbling B: Bubbling > Target > Capturing C: Target > Bubbling > Capturing D: Capturing > Target > Bubbling

在捕获(capturing)阶段中,事件从祖先元素向下传播到目标元素。当事件达到目标(target)元素后,冒泡(bubbling)才开始。


1
2
3
4
let number = 0
console.log(number++)
console.log(++number)
console.log(number)

一元后自增运算符 ++:

返回值(返回 0) 值自增(number 现在是 1) 一元前自增运算符 ++:

值自增(number 现在是 2) 返回值(返回 2)


1
const sum = eval('10*10+5');

代码以字符串形式传递进来,eval 对其求值。如果它是一个表达式,就像本例中那样,它对表达式求值。表达式是 10 * 10 + 5。这将返回数字 105。


1
2
3
4
5
6
7
8
const a = {}
const b = { key: 'b' }
const c = { key: 'c' }

a[b] = 123
a[c] = 456

console.log(a[b])

对象的键被自动转换为字符串。我们试图将一个对象 b 设置为对象 a 的键,且相应的值为 123。

然而,当字符串化一个对象时,它会变成 “[Object object]”。因此这里说的是,a[“Object object”] = 123。然后,我们再一次做了同样的事情,c 是另外一个对象,这里也有隐式字符串化,于是,a[“Object object”] = 456。

然后,我们打印 a[b],也就是 a[“Object object”]。之前刚设置为 456,因此返回的是 456。


1
2
3
4
5
6
7
8
const person = { name: 'Lydia' }

function sayHi(age) {
console.log(`${this.name} is ${age}`)
}

sayHi.call(person, 21)
sayHi.bind(person, 21)

Lydia is 21 function

使用这两种方法,我们都可以传递我们希望 this 关键字引用的对象。但是,.call 是立即执行的。

.bind 返回函数的副本,但带有绑定上下文!它不是立即执行的。


1
2
3
4
5
6
7
下面哪些值是 falsy?
0
new Number(0)
;('')
;(' ')
new Boolean(false)
undefined

只有 6 种 falsy 值:

undefined null NaN 0 ‘’ (empty string) false

Function 构造函数, 比如 new Number 和 new Boolean,是 truthy。


1
2
3
4
5
6
7
8
9
10
11
;(() => {
let x, y
try {
throw new Error()
} catch (x) {
;(x = 1), (y = 2)
console.log(x)
}
console.log(x)
console.log(y)
})()

catch 代码块接收参数 x。当我们传递参数时,这与之前定义的变量 x 不同 。这个 x 是属于 catch 块级作用域的。

然后,我们将块级作用域中的变量赋值为 1,同时也设置了变量 y 的值。现在,我们打印块级作用域中的变量 x,值为 1。

catch 块之外的变量 x 的值仍为 undefined, y 的值为 2。当我们在 catch 块之外执行 console.log(x) 时,返回 undefined,y 返回 2。

文章作者: Kwin
文章链接: http://huangkun.host/2020/03/25/20190603-面试题/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Kwin 's Blog
打赏
  • 微信
    微信
  • 支付宝
    支付宝

评论