我正在辨别著名的JS的extend
功能:
function extend(parent, child) {
var F = new Function();
F.prototype = parent.prototype;
child.prototype = new F();
//child.prototype.constructor = Child
}
我已经注释掉了构造函数属性被覆盖的那一行。如果我通过以下方式创建对象:
var p = function p() {this.parent = true};
var c = function c() {this.child = true};
extend(p, c);
console.log((new c()).constructor); //outputs reference to `p` constructor, why?
我的问题是为什么构造函数引用var p = function p() {this.parent = true};
而不是变量F
指向的匿名函数?有关构造函数属性的手册指出,constructor property returns a reference to the Object function that created the instance's prototype
实例原型new F()
是由匿名函数创建的。那么,为什么指向另一件事呢?
更新
我根据HMR
的答案做出的以下假设正确吗?
创建新函数时,JS引擎会创建一个新的空对象,并设置prototype
该函数的属性以指向此新创建的对象。然后,JS引擎constructor
向该对象添加一个属性,该属性指向创建的函数。
所以现在我的情况。当var F = new Function()
JS引擎时:
1)创建新F
函数
2)创建新对象(顺便说一下oF
)
3)设置原型F.prototype = oF
4)设置构造函数oF.constructor = F
这同样适用于function p
有其原型oP
与构造属性设置为function p
。我们记得,F.prototype
指向,oF
但是执行以下行后F.prototype = parent.prototype
,现在指向oP
。然后,当我们访问(new c()).constructor
属性new c()
对象时,它就没有了,因此JS引擎开始向后看原型,并在oP
指向该对象时找到了属性function p
-这正是我所得到的。
如果在实例上找不到成员,则JS引擎将在原型链中查找。原型链是一堆具有__proto__
另一个对象的对象,直到它为空。
请注意,这__proto__
是一个非标准属性,在此用于解释原型链中首先使用的对象。
由于您将child.prototype替换为具有__proto__
parent.prototype的空对象,因此JS引擎无法在c上找到构造函数,child.prototype
但随后它将在child.prototype.__proto__
parent.prototype上找到它。
当您这样做时:
child.prototype.constructor=child;
它将其添加到child.prototype中,因此不会突变in中的parent.prototype child.prototype.__proto__
。这称为阴影。
更多关于原型和构造函数的信息。
[更新]
继承后的原型链如下所示:
insance of child (new c())
=> c.prototype === new F() so an empty object
=> p.prototype, set when you did F.prototype=parent.prototype
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句