没有办法在JavaScript中找到对象的真正构造函数吗
我正在认真审查ECMAScript 5.1规范 我很好奇是否有一种方法可以告诉ES5中对象的“真正构造函数”是什么。(不是显式的“构造函数”属性) 根据规范,显式“构造函数”属性只是从函数对象的副产品对象到函数对象的初始反向引用 (这里,副产品是最初由函数对象的显式“原型”属性指向的对象。) 因此,显式“构造函数”属性与对象的实际构造函数无关:没有办法在JavaScript中找到对象的真正构造函数吗,javascript,Javascript,我正在认真审查ECMAScript 5.1规范 我很好奇是否有一种方法可以告诉ES5中对象的“真正构造函数”是什么。(不是显式的“构造函数”属性) 根据规范,显式“构造函数”属性只是从函数对象的副产品对象到函数对象的初始反向引用 (这里,副产品是最初由函数对象的显式“原型”属性指向的对象。) 因此,显式“构造函数”属性与对象的实际构造函数无关: function Foo(name){ this.name = name; } var foo = new Foo("Brian"); var bar
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 === Foo // false
foo2.constructor === Object // true
由于foo2没有像往常一样拥有自己的“constructor”属性,因此,读取foo2.constructor实际上是[[Prototype]]链查找,即foo2.constructor-->((foo2.[Prototype]])。constructor-->bar.constructor,它是对象,而不是Foo
您可以通过以下方式进行检查:
Object.getPrototypeOf(foo2) === bar // true
foo2.constructor === Foo // false
foo2.constructor === Object // true
最后,没有办法从对象foo2中找到Foo吗
加:
我说的是ES5。请不要带任何依赖于引擎或ES6的东西(例如,
\uuuuu proto\uuuuu
)不,语言本身不提供任何这样做的功能
如果我们查阅,我们会发现它主要是对函数的[[Construct]]
内部方法的调用。把我们的注意力转向,我们看到:
当调用函数对象F的[[Construct]]内部方法时,参数列表可能为空,将执行以下步骤:
对象”
”true
prototype
”的F的[[Get]]内部属性的值new
创建的对象的唯一处理是设置其[[Prototype]]]
,然后将其交给函数的[[Call]]
方法在步骤8中进行处理。如果分配给对象的[[Prtototype]]
的值不包含准确的构造函数
属性,则无法知道是哪个构造函数创建了对象
当然,您可以通过在创建时在对象上设置一个值,将该信息存储在您自己的构造函数代码中,但JavaScript引擎不会为您这样做。好的,我将在这里指出这是不可能的。据我所知,没有任何东西能将构造函数与构造的对象牢固地联系起来。您可以在创建对象后更改
Foo.prototype
,甚至Foo的foo2 instanceof Foo
将不再工作。只需将构造函数看作一个蓝图。您可以使用它来创建一个对象,但是在您创建它之后,没有任何东西可以阻止您对这两个对象执行完全不同的操作。另外,不要忘记,构造函数完全可以返回一个全新的对象,而不是隐式的返回此
,在这种情况下,绝对没有指向创建它的函数的链接。好了,现在看起来又清楚了。实际上,我很好奇Chrome控制台在上面的例子中正确地给出了真正的构造函数。所以,必须是引擎的内部实现不公开。