首先我们来看一道题:
class A {
say() {
console.log('foo')
}
}
let a = new A()
A.prototype = {
say() {
console.log('bar')
}
}
a.say()
乍看这道题,也许你会有点萌萌哒,这题想干锤子?
没事我们来简化一下:
function A(){}
let a = new A()
A.prototype = {
say() {
console.log('bar')
}
}
a.say()
好的,来分析一下这个。
let a = new A()
语句执行之后,a.__proto__
已经指向了A.prototype
,在这条语句之后重写A.prototype
,并不会影响a.__proto__
的指向,因此 报错。如果把let a = new A()
放在A.prototype = {...}
之后,a.__proto__
会指向重定义后的A.prototype
,这样的话会输出bar
。
回到题目,根据以上的分析,会输出foo
,如果把let a = new A()
放在A.prototype = {...}
之后,会输出bar
。等等,真的跟你想的一样会输出bar
?
小伙子,sometime is naive啊!
为啥不输出bar
?我们进一步探讨
可以看到,我的js引擎对class A的prototype的定义中,writable:false。也就是class的prototype是不可重写的!
但是!有的小伙伴的chrome中:
。。。。
writable:true
!
好了,结论出来了。这题虽然想考的是实力对象的__proto__
的指向,但是他没注意到不同版本的chrome对class的prototype定义不一样。正常情况应该是不可重写的。