我一直在尝试使用JavaScript世界知名的原型继承实现。到目前为止,除了一件事以外,一切对我都有意义......
function base() {
this.a = "baseObj property";
}
base.thisIs = "base constructor";
function derived() {
this.b = "derivedObj property";
}
derived.thisIs = "derived constructor";
var baseObj = new base();
到目前为止一切顺利。 baseObj.a
返回“baseObj property”,baseObj.constructor.thisIs
返回“base constructor”。
但是当我真正使某些东西继承了基础对象的值时,事情开始让我感到困惑。
derived.prototype = baseObj;
derivedObj = new derived();
最终发生的事情是derivedObj.a
返回“baseObj property”。好。 derivedObj.b
返回“derivedObj property”。再好。但derivedObj.constructor.thisIs
返回“基础构造函数” ...
为了实现这一目标,口译员必须在derivedObj.constructor
中找不到derivedObj
。那么它的作用是在derivedObj.__proto__
之后搜索那里。由于new
关键字设置derivedObj.__proto__
等于derived.prototype
,我们之前设置为baseObj
,derivedObj.__proto__
最终返回baseObj
。
这可以解释为什么derivedObj.constructor
被遗忘了。它似乎毫无用处。口译员不需要用它来获取derived.prototype
;他们可以使用derivedObj.__proto__
。然而,事实是,可能对于使用derivedObj.constructor
以获取derived.thisIs
的值非常有用。
但即便如此。它没有解释为什么在baseObj
中没有被遗忘。为什么.constructor
存在baseObj
而derivedObj
存在new
?它们以完全相同的方式初始化。使用// /*This is a comment
关键字。
答案 0 :(得分:3)
默认情况下,函数具有prototype
属性,该属性是在将函数用作构造函数时实例继承的对象。 prototype
对象具有constructor
属性,该属性指向函数。
derived.prototype = baseObj
的问题在于您替换了整个prototype
,因此您丢失了返回derived.prototype.constructor
的原始derived
。
解决问题的方法是重新分配该属性:
derived.prototype = baseObj;
derived.prototype.constructor = derived;
然而,这将改变baseObj
对象。这通常是不受欢迎的,所以正确的方法是
derived.prototype = Object.create(baseObj);
derived.prototype.constructor = derived;