没有办法在JavaScript中找到对象的真正构造函数吗

没有办法在JavaScript中找到对象的真正构造函数吗,javascript,Javascript,我正在认真审查ECMAScript 5.1规范 我很好奇是否有一种方法可以告诉ES5中对象的“真正构造函数”是什么。(不是显式的“构造函数”属性) 根据规范,显式“构造函数”属性只是从函数对象的副产品对象到函数对象的初始反向引用 (这里,副产品是最初由函数对象的显式“原型”属性指向的对象。) 因此,显式“构造函数”属性与对象的实际构造函数无关: function Foo(name){ this.name = name; } var foo = new Foo("Brian"); var bar

我正在认真审查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 === 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]]内部方法时,参数列表可能为空,将执行以下步骤:

  • 让obj成为新创建的本机ECMAScript对象
  • 按照8.12的规定设置obj的所有内部方法
  • 将obj的[[Class]]内部属性设置为“
    对象”
  • 将obj的[[Extensible]]内部属性设置为
    true
  • 让proto成为调用带有参数“
    prototype
    ”的F的[[Get]]内部属性的值
  • 如果Type(proto)是Object,则将obj的[[Prototype]]内部属性设置为proto
  • 如果Type(proto)不是Object,则将obj的[[Prototype]]内部属性设置为标准内置对象Prototype对象,如15.2.4所述
  • 让result作为调用F的[[Call]]内部属性的结果,提供obj作为this值,并提供作为args传递到[[Construct]]的参数列表
  • 如果类型(结果)是对象,则返回结果
  • 返回obj
  • 正如您在步骤5到7中所看到的,环境对
    new
    创建的对象的唯一处理是设置其
    [[Prototype]]]
    ,然后将其交给函数的
    [[Call]]
    方法在步骤8中进行处理。如果分配给对象的
    [[Prtototype]]
    的值不包含准确的
    构造函数
    属性,则无法知道是哪个构造函数创建了对象


    当然,您可以通过在创建时在对象上设置一个值,将该信息存储在您自己的构造函数代码中,但JavaScript引擎不会为您这样做。

    好的,我将在这里指出这是不可能的。据我所知,没有任何东西能将构造函数与构造的对象牢固地联系起来。您可以在创建对象后更改
    Foo.prototype
    ,甚至
    Foo的
    foo2 instanceof Foo
    将不再工作。只需将构造函数看作一个蓝图。您可以使用它来创建一个对象,但是在您创建它之后,没有任何东西可以阻止您对这两个对象执行完全不同的操作。另外,不要忘记,构造函数完全可以返回一个全新的对象,而不是隐式的
    返回此
    ,在这种情况下,绝对没有指向创建它的函数的链接。好了,现在看起来又清楚了。实际上,我很好奇Chrome控制台在上面的例子中正确地给出了真正的构造函数。所以,必须是引擎的内部实现不公开。