var ninja = {
name: 'Ninja',
say: function () {
return 'I am a ' + this.name;
}
};
function F(){
}
F.prototype = ninja;
var ninja2 = new F();
ninja2.name;
Output >>> "Ninja"
ninja2.constructor === F
Output >>> false
ninja2.constructor
Output >>> function Object()
ninja2.__proto__ === ninja
Output >>> true
在此示例中,为什么F
ninja2
的构造函数不是Hero
(正如人们所料)?!
我希望这是因为...下一个例子打印function Hero(){ }
var h1 = new Hero();
h1.constructor
Output >>> function Hero()
。
F.prototype = ninja;
概念上有什么区别?
我认为这与我在第一个例子中明确设置F
的事实有关。但它与此有何关系?我很困惑。 ninja2
的构造函数new F()
不是ninja2
吗?在使用{{1}}创建{{1}}之后?
答案 0 :(得分:2)
constructor
属性没有魔力,它只是在创建函数对象时自动添加的属性:
13.2 Creating Function Objects
- 创建一个新的本机ECMAScript对象,让 F 成为该对象。
- ...
- 让 proto 是创建一个新对象的结果,该对象将由表达式
new Object()
构造,其中Object
是具有该名称的标准内置构造函数。 / LI>- 使用参数"
constructor
&#34;,Property Descriptor {[[Value]]调用 proto 的[[DefineOwnProperty]]内部方法:< em> F ,{ [[可写]]: true ,[[Enumerable]]: false ,[[Configurable]]: true }, false 。- 使用参数&#34;
prototype
&#34;,Property Descriptor {[[Value]]调用 F 的[[DefineOwnProperty]]内部方法:< EM>原, {[[可写]]: true ,[[Enumerable]]: false ,[[Configurable]]: false }和 false 。- ...
示例:
function F(){}
F.prototype.constructor; // F
因此,当您使用其他对象覆盖F.prototype
时,您将失去constructor
属性。
然后,当您使用ninja2.constructor
时,您会获得Object
因为:
ninja2
没有自己的constructor
属性。ninja2
继承自ninja
,其中没有constructor
属性。ninja
继承自Object.prototype
,其constructor
属性设置为Object
。要解决此问题,您可以
在constructor
中恢复F.prototype
:
function F(){}
F.prototype = ninja;
F.prototype.constructor = F;
在constructor
中加入ninja
:
var ninja = {
constructor: F, /* ... */
};
将所需的属性添加到F.prototype
,而不是将其替换为另一个对象:
Object.assign(F.prototype, ninja); /* Requires ECMAScript 6 */
答案 1 :(得分:1)
你宣布&#34; F&#34;如下:
function F(){}
这将创建一个功能对象&#34; F&#34;这样的原型:
F.prototype = { constructor: F };
&#34; ninja&#34;您创建的对象默认具有Object()构造函数。用'&#34; ninja&#34;替换F.prototype时。对象,下面的代码行现在使用来自&#34; ninja&#34;的Object()构造函数。因为你覆盖了F&#39的原型:
var ninja2 = new F();