首先我们来看一道题:
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?

image.png
小伙子,sometime is naive啊!
为啥不输出bar?我们进一步探讨

image.png
可以看到,我的js引擎对class A的prototype的定义中,writable:false。也就是class的prototype是不可重写的!
但是!有的小伙伴的chrome中:

image.png
。。。。

image.png
writable:true!
好了,结论出来了。这题虽然想考的是实力对象的__proto__的指向,但是他没注意到不同版本的chrome对class的prototype定义不一样。正常情况应该是不可重写的。