一道关于原型链的面试题
昨天在面试的时候碰到一道原型链的问题,本以为自己对原型链的八股已经烂熟于心,这种实际问题应该问题不大,可事实上自己还是无法解答。没有动手实操,果然不行!
问题:
function Person(age){
this.age= age;
}
const p1 = new Person(12);
Person.prototype.a = 2
p1.a?
Person.a?
我最开始面对这题,我想的是:
- 当我们尝试访问一个对象的属性(如
p1.a
)时,JavaScript引擎首先检查这个对象本身是否有这个属性。 - 如果没有找到,引擎会继续在对象的原型链上查找这个属性。在这个例子中,
p1
对象的原型是Person.prototype
。 - 由于我们给
Person.prototype
添加了属性a
(Person.prototype.a = 2
),p1
对象可以通过原型链访问到这个属性,所以p1.a
的值是2
。
那么Person.a不就也是2吗?也顺着原型链呗,它的原型链不也会有Person.prototype
呗。
可我犯了严重的概率混淆问题!
对象实例的原型链
当我们通过new Person()
创建一个对象实例时,这个实例的内部原型(通常通过__proto__
属性访问)会被设置为构造函数的prototype
属性。因此,如果实例本身没有某个属性或方法,JavaScript引擎会沿着这个原型链向上查找,直到找到该属性或方法为止,或直到原型链的末端。这就是为什么p1.a
能够访问到Person.prototype.a
的原因。
- 实例的原型链上有其构造函数的原型对象!
函数对象的原型链
函数对象(如Person
)也是对象,因此它们也有自己的原型链。所有的函数默认继承自Function.prototype
,这也意味着它们最终继承自Object.prototype
。然而,这条原型链与实例的原型链是不同的。
- Person.prototype 这个属性可见是构造函数所特有的,实例对象是没有的。
- 构造函数的原型链是它的构造函数的原型对象,这里是
Function.prototype
。
总结:实例对象的原型链和其构造函数的原型链走得不是一条路子。
转载自:https://juejin.cn/post/7350978133703344182