Object.create是否可以配合类的私有字段和私有方法使用?
结论:无法用和普通无私有字段类相同的
Object.create方式直接创建带私有字段的类实例 普通类的Object.create写法成立的原因
普通类的公有属性没有额外的访问校验规则,你用Object.create(Normal.prototype, { value: { value: 123 } })创建的对象,既满足了原型指向类原型的要求,也手动添加了需要的公有属性,自然可以正常调用类的原型方法。
class Normal { constructor(value) { this.value = value } valueOf() { return this.value } } const n = Object.create(Normal.prototype, { value: { value: 123 } }) n.valueOf() // 123
带私有字段类报错的核心原因
- JS 私有字段(
#开头的类成员)有严格的品牌校验机制:只有被对应类的构造函数实际初始化过的对象,才会被识别为该类的合法实例,才能访问对应的私有字段。 - 你直接用
Object.create创建对象时,仅手动设置了对象原型为Normal.prototype,完全没有运行Normal的构造函数,因此这个对象上既没有被安装#value私有字段,也没有对应的合法实例标记,调用valueOf()访问私有字段时自然会抛出attempted to get private field on non-instance错误。 - 注意你在
Object.create第二个参数中定义的value是普通公有属性,和类内部的私有字段#value是完全独立的两个属性,没有任何关联。
class Normal { #value constructor(value) { this.#value = value } valueOf() { return this.#value } } const n = Object.create(Normal.prototype, { value: { value: 123 } }) n.valueOf() // Error("attempted to get private field on non-instance")
可行的实现方案
私有字段只能在类构造函数执行时被安装到实例上,只要保证构造函数正常执行完成即可,标准写法直接用new调用构造函数:
const n = new Normal(123) n.valueOf() // 123
如果有特殊场景需要自定义实例创建逻辑,可以用Reflect.construct完成创建,本质上还是会走完整的构造函数初始化流程,保证私有字段被正确安装。
内容的提问来源于stack exchange,提问作者joelnet
相关产品推荐
相关产品推荐

