我读了一篇article来解释原型链是什么。
它说如果我尝试访问对象的属性但它没有它,javascript引擎将尝试它.constructor.propotype
。如果没有,请尝试.construtor.propotype.constructor.propotype
。直到它找到内置的Object()。
但我测试了这个:
function a() {}
b = new a();
然后:
c = b.constructor.prototype
我得到一个空的a
对象。
然后:
d = c.constructor.prototype
我得到一个空的a
对象。
它循环。无论我调用了多少.constructor.prototype
,它都找不到Object()。怎么了?我是否误解了原型链?
答案 0 :(得分:2)
在JS OOP中,constructor
和prototype
属性是不稳定的,因为在执行继承时它们不会为您设置。您应该手动设置/更改它们以实现继承。例如,请参阅this tutorial。
看起来你试图爬上原型链的方式(通过遍历.constructor.prototype
)从未真正到达Object
顶级原型,因为当你有function a(){}
时未设置正确的constructor
和prototype
属性。我甚至无法将它们强迫进入a
;在Chrome中我得到:
> function a(){}
undefined
> a.constructor.prototype
function Empty() {}
> a.constructor.prototype = Object.prototype
Object
> a.constructor.prototype
function Empty() {} // hmmmm, the assignment didn't take...
当然运行时不需要这样做,因为它引用了每个对象的实际原型。即该语言不通过.constructor.prototype
进行查找,它会在内部保存每个实例的原型。因此,如果您使用.constructor.prototype
代替.__proto__
:
function a(){}
b = new a();
b.__proto__ === Object.prototype; // false
b.__proto__.__proto__ === Object.prototype; // true since we reached the top of the prototype chain
重要的是要注意,属性__proto__
从未成为标准,并且在ES5中标准化的方式略有不同:
obj.__proto__ === Object.getPrototypeOf(obj);
这会弃用.__proto__
。
答案 1 :(得分:1)
看起来我问了一个愚蠢的问题。
如果A是函数:
A.prototype.constructor === A
如果A不是函数:
正常财产中的A.prototype。
所以(在标准中)没有办法爬上原型链。