JavaScript - 意外/奇怪的构造函数
JavaScript - unexpected/strange constructor
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
?
constructor
属性没有魔力,它只是创建函数对象时自动添加的属性:
13.2 创建函数对象
- 创建一个新的本机 ECMAScript 对象,并让 F 成为该对象。
- 。
- 让 proto 是创建一个新对象的结果,该对象将由表达式构造
new Object()
其中Object
是具有该名称的标准内置构造函数。- 调用 [[DefineOwnProperty]] 带有参数 "
constructor
" 的 proto 内部方法, 属性描述符 {[[Value]]: F, { [[可写]]: 真, [[可枚举]]: 假, [[可配置]]: 真},和假。- 用参数"
prototype
"调用 F 的 [[DefineOwnProperty]] 内部方法, 属性描述符 {[[Value]]: proto, { [[可写]]: true, [[Enumerable]]: false, [[Configurable]]: 假},和假。- 。
例:
function F(){}
F.prototype.constructor; // F
因此,当您用另一个对象覆盖F.prototype
时,您将丢失 constructor
属性。
然后,当您使用 ninja2.constructor
时,您会得到Object
,因为:
-
ninja2
没有自己的constructor
财产。 -
ninja2
继承自ninja
,而没有自己的constructor
属性。 -
ninja
继承自Object.prototype
,后者将自己的constructor
属性设置为Object
。
要解决此问题,您可以
在
F.prototype
中恢复constructor
:function F(){} F.prototype = ninja; F.prototype.constructor = F;
在
ninja
中包含constructor
:var ninja = { constructor: F, /* ... */ };
将所需的属性添加到
F.prototype
,而不是将其替换为另一个对象:Object.assign(F.prototype, ninja); /* Requires ECMAScript 6 */
你声明"F"如下:
function F(){}
这将创建一个函数对象"F",其原型如下所示:
F.prototype = { constructor: F };
默认情况下,您创建的"ninja"对象具有 Object(( 构造函数。当您将 F.prototype 替换为 "ninja" 对象时,以下代码行现在使用 "ninja" 中的 Object(( 构造函数,因为您覆盖了 F 的原型:
var ninja2 = new F();
相关文章:
- ES6构造函数返回基类的实例
- 使用Google Visualization动态调用构造函数
- javascript中对象构造函数中的var属性与this.properties
- 理解typescript中的构造函数接口
- 为什么构造函数不是构造函数
- 如果在构造函数中有“返回”,则在 JavaScript 中的新运算符中做了什么
- 拦截对构造函数的调用
- 使用闭包共享构造函数参数
- 文本表示法VS.构造函数,用于在JavaScript中创建对象
- 从js引擎的角度来看闭包和构造函数是如何工作的
- 如何使用此从对象访问构造函数
- Javascript:为什么是构造函数's __proto__属性Empty(){}
- 当一个重要的构造函数参数丢失时应该发生什么
- Chrome Javascript日期构造函数错误
- 如何使用构造函数's的输出,以便将值插入到对象中
- 为什么在调用父构造函数时在[]中发送数据
- JavaScript - 意外/奇怪的构造函数
- TypeScript-NodeJS-意外的令牌'构造函数、函数、访问器或变量'
- 当使用类似的参数调用日期构造函数时,会提供意外的结果
- 意外的“;双“;在子模块中使用构造函数时使用命名空间