【问题标题】:Can fn.constructor be different from Object.getPrototype(fn).constructor?fn.constructor 可以与 Object.getPrototype(fn).constructor 不同吗?
【发布时间】:2021-11-18 10:47:09
【问题描述】:

我正在编写一个序列化对象的程序。作为其中的一部分,我需要从实例中获取类,以便将来创建一个新实例。我注意到我可以调用fn.constructorObject.getPrototypeOf(fn).constructor 来获取实例来自的类。例如:

class Foo {}
const myFoo = new Foo();

const constructor1 = myFoo.constructor;
const constructor2 = Object.getPrototypeOf(myFoo).constructor;

在上面,constructor1constructor2 似乎总是相同的,除非我手动将它们设置为其他值。是否存在这些值会不同的情况?

【问题讨论】:

  • 除非我手动将它们设置为其他值”是什么意思?
  • "是否存在这些值会不同的情况?" - 你是只考虑classes 的实例还是任意对象?
  • "我正在编写一个序列化对象的程序。" - 我建议为此调用 .toJSON(),而不是依赖一些构造函数。一个对象可能拥有一些内部状态,如果知道特定的类,您就无法恢复这些状态。
  • 你为什么在标记为ecmascript-5的问题中使用class语法和Object.getPrototypeOf
  • 1.像 obj.constructor = 'foo', 2, 任意对象, 3. 我正在处理的程序知道类,这就是它可以恢复状态的原因, 4. 这是我的错误,我将删除标签

标签: javascript object constructor prototype


【解决方案1】:

当它们不同时,您已经确定了情况。

当您调用Object.getPrototypeOf(myFoo).constructor 时,您访问的是Foo 原型实例的constructor 属性。

如果您的 Foo 实例没有直接定义 constructor,则访问它“通过”myFoo 并点击 Foo.prototype。因此,两者唯一不同的情况是您手动重新定义myFoo 上的constructor 属性,就像您说的那样:

myFoo.constructor = NotFoo

在这种情况下,JavaScript 直接在 myFoo 实例上创建一个属性,因此访问 myFoo.constructor 永远不会“通过”到 Foo.prototype

有趣的情况是当您处理继承时:

class Foo1 {}
class Foo2 extends Foo1{}

const myFoo2 = new Foo2()

const proto1 = Object.getPrototypeOf(myFoo2)
const proto2 = Object.getPrototypeOf(proto1)

proto1.constructor  // Foo2
proto2.constructor  // Foo1

【讨论】:

  • 两者唯一不同的时候” - 不是真的:-)
  • @Bergi 你是什么意思?
  • 我的意思是还有很多其他方法可以修改程序,使它们不一样
【解决方案2】:

是否存在这些值不同的情况?

当然,不只是那些在实例上手动设置.constructor 对象的地方。

也存在具有这种.constructor 属性的“普通”对象,即Foo.prototype 之类的原型对象。

另一种情况是没有原型的对象,例如 Object.create(null)Object.prototype,其中一个表达式会导致异常,但其他表达式会起作用。

那么可能存在(解释).constructor 是一个 getter,它在实例和原型对象本身上调用时返回不同的值。

最后,不要忘记constructor1constructor2 可能是相同的值,但不一定会像您期望的那样起作用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-17
    • 2011-03-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-20
    • 1970-01-01
    相关资源
    最近更新 更多