TypeError: 私有字段/方法中两次初始化对象是一个错误
消息
TypeError: Cannot initialize #x twice on the same object (V8-based) TypeError: Initializing an object twice is an error with private fields (Firefox) TypeError: Cannot redefine existing private field (evaluating 'super(o)') (Safari) TypeError: Cannot initialize private methods of class X twice on the same object (V8-based) TypeError: Initializing an object twice is an error with private methods (Firefox) TypeError: Cannot install same private methods on object more than once (evaluating 'super(o)') (Safari)
错误类型
哪里出错了?
对于任何对象,如果它已经包含私有字段或方法,则再次安装相同的字段将是错误的。当调用类构造函数时,私有属性会安装在 this
的值上,因此如果 this
值是该类的已构造实例,则可能会发生此错误。
通常,构造函数中的 this
是一个新创建的对象,它没有任何预先存在的属性。但是,它可以被基类的返回值覆盖。如果基类返回另一个对象,则该对象将替换当前对象作为 this
的值
js
class Base {
constructor(o) {
// This object will become the this value of any subclass
return o;
}
}
class Derived extends Base {
#x = 0;
}
如果调用 new Derived(anyObject)
,其中 anyObject
不是 Derived
的实例,则 Derived
构造函数将以 anyObject
作为 this
值被调用,因此将在 anyObject
上安装 #x
私有字段。这是“返回值覆盖”技巧,它允许您在不相关对象上定义任意信息。但是,如果再次调用 new Derived(new Derived())
或调用 new Derived(anyObject)
,则 Derived
构造函数将尝试在已具有 #x
私有字段的对象上再次安装 #x
私有字段,从而导致此错误。