【发布时间】:2015-10-07 17:01:55
【问题描述】:
我正在认真审查 ECMAScript 5.1 规范。
我很好奇是否有办法告诉 ES5 中对象的“真正的构造函数”是什么。 (不是显式的“构造函数”属性)
根据规范,显式“构造函数”属性只是从函数对象的副产品对象到函数对象的初始反向引用。
(这里,副产品是函数对象的显式“原型”属性最初指向的对象。)
因此,显式的“构造函数”属性与对象的真正构造函数无关:
function Foo(name){ this.name = name; }
var foo = new Foo("Brian");
var bar = { a: 10, b: function(){ if(this.name) return this.name; }};
Foo.prototype = bar;
var foo2 = new Foo("John"); // Let me call Foo as "real constructor" of foo2
这里,即使 foo2 是由 Foo 创建的,由于 Foo.prototype 在创建 foo2 的那一刻指向 bar,所以 foo2 的内部 [[Prototype]] 指向 bar,我们可以通过以下方式检查:
Object.getPrototypeOf(foo2) === bar // true
由于 foo2 没有像往常一样拥有自己的“constructor”属性,所以,读取 foo2.constructor 实际上是 [[Prototype]] 链式查找,即 foo2.constructor --> (( foo2.[[Prototype] ] )).constructor --> bar.constructor 是 Object,而不是 Foo。
您可以通过以下方式检查:
foo2.constructor === Foo // false
foo2.constructor === Object // true
最后,有没有办法从对象 foo2 中找到 Foo?
添加:
我说的是 ES5。请不要带任何依赖引擎或 ES6 的东西(例如 __proto__ )
【问题讨论】:
-
好吧,我要在这里冒险并说这是不可能的。据我所知,没有什么可以将构造函数与构造对象牢固地联系起来。您可以在创建对象后更改
Foo.prototype,甚至foo2 instanceof Foo将不再起作用。只需将构造函数视为蓝图。你用它来创建一个对象,但在你创建它之后,没有什么能阻止你对它们做完全不同的事情。 -
另外,不要忘记构造函数完全有可能返回一个全新的对象而不是隐含的
return this,在这种情况下绝对没有链接回到创建它的函数。
标签: javascript