new x().constructor 实际上并不存在?

new x().constructor doesn't ACTUALLY exist?

我一直在试验 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 returns "baseObj property"baseObj.constructor.thisIs returns "base constructor".

但是当我实际让某些东西继承基础对象的值时,事情开始让我感到困惑。

derived.prototype = baseObj;
derivedObj = new derived();

最终发生的事情是 derivedObj.a returns "baseObj property"。好的。 derivedObj.b returns "derivedObj property"。又好了。但是derivedObj.constructor.thisIsreturns"base constructor"...

要发生这种情况,解释器必须无法在 derivedObj 中找到 derivedObj.constructor。那么它的作用是跟随 derivedObj.__proto__ 到那里搜索。因为 new 关键字将 derivedObj.__proto__ 设置为 derived.prototype,我们之前将其设置为 baseObjderivedObj.__proto__ 最终返回 baseObj

这可以解释为什么 derivedObj.constructor 被遗忘了。貌似没什么用解释器不需要使用它来获取 derived.prototype;他们可以只使用 derivedObj.__proto__。然而,现实情况是 可以 使用 derivedObj.constructor 以获得 derived.thisIs.

的值。

但即便如此。它没有解释为什么它 没有 baseObj 中被遗忘。为什么 baseObj 中存在 .constructorderivedObj 中不存在?它们的初始化方式完全相同。使用 new 关键字。

默认情况下,函数有一个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;