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.thisIs
returns"base constructor"...
要发生这种情况,解释器必须无法在 derivedObj
中找到 derivedObj.constructor
。那么它的作用是跟随 derivedObj.__proto__
到那里搜索。因为 new
关键字将 derivedObj.__proto__
设置为 derived.prototype
,我们之前将其设置为 baseObj
,derivedObj.__proto__
最终返回 baseObj
。
这可以解释为什么 derivedObj.constructor
被遗忘了。貌似没什么用解释器不需要使用它来获取 derived.prototype
;他们可以只使用 derivedObj.__proto__
。然而,现实情况是 可以 使用 derivedObj.constructor
以获得 derived.thisIs
.
的值。
但即便如此。它没有解释为什么它 没有 在 baseObj
中被遗忘。为什么 baseObj
中存在 .constructor
而 derivedObj
中不存在?它们的初始化方式完全相同。使用 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;
我一直在试验 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.thisIs
returns"base constructor"...
要发生这种情况,解释器必须无法在 derivedObj
中找到 derivedObj.constructor
。那么它的作用是跟随 derivedObj.__proto__
到那里搜索。因为 new
关键字将 derivedObj.__proto__
设置为 derived.prototype
,我们之前将其设置为 baseObj
,derivedObj.__proto__
最终返回 baseObj
。
这可以解释为什么 derivedObj.constructor
被遗忘了。貌似没什么用解释器不需要使用它来获取 derived.prototype
;他们可以只使用 derivedObj.__proto__
。然而,现实情况是 可以 使用 derivedObj.constructor
以获得 derived.thisIs
.
但即便如此。它没有解释为什么它 没有 在 baseObj
中被遗忘。为什么 baseObj
中存在 .constructor
而 derivedObj
中不存在?它们的初始化方式完全相同。使用 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;