【问题标题】:Not able to update a class property in ES6无法在 ES6 中更新类属性
【发布时间】:2023-03-28 13:52:01
【问题描述】:

这如何转化为 ES6?

function Mock() { };
Mock.prototype.foo = 'bar';
var obj = new Mock();
console.log(obj.foo);
Mock.prototype.foo = 'Something else';
console.log(obj.foo);

我试过了:

class Mock {
  foo = 'bar';
}
const obj = new Mock();
console.log(obj.foo);
Mock.prototype.foo = 'Something else';
console.log(obj.foo);

但它不起作用,因为类属性实际上是直接附加到实例化对象而不是附加到Mock.prototype

【问题讨论】:

  • 您可以从 proto console.log(obj.__proto__.foo); //'Something else' 访问父 foo
  • @DenisStukalov 如果我只有Mock 的参考资料怎么办?
  • @DenisStukalov,最好不要建议使用已弃用的属性
  • @ChristopherRonning 会有什么帮助?我想更新 prototype 以便它也更新所有对象实例
  • @GuerricP 类字段是来自 stage-3 proposal 的实验性语法。如果有的话,它们可能会成为 ES2021 或更高版本的一部分。在 ES6 中,您应该只写一个 constructor() 来创建属性,这也清楚地表明它们是在实例上创建的。

标签: javascript ecmascript-6 prototype


【解决方案1】:

对我来说,更改原型似乎是一种反模式。但是如果你真的想要这个,你应该继续使用与之前相同的语法来定义属性:

class Mock { }
Mock.prototype.foo = "bar";

const obj = new Mock();
console.log(obj.foo);
Mock.prototype.foo = "Something else";
console.log(obj.foo);

【讨论】:

  • 如果它是一个反模式,为什么它被允许?为了向后兼容旧版网络?
  • 这是一个有趣的问题,但这需要 tc39 小组来回答。无论如何,语言规范永远不可能消除所有反模式。
  • 好的,我认为这是解决这个问题的好方法:stackoverflow.com/questions/62178687/…。这可能超出了问题的范围,但是您将如何解决呢? Proxy?还有什么?
  • @GuerricP 这是允许的,因为很难阻止它。如果您需要,覆盖方法也非常有用。将原型对象视为可变存储仍然是个坏主意。
【解决方案2】:
  • 因为在 ES6 中,类的 .prototype 属性是不可写的 并且不可配置
  • 如果您想更改,请使用 Object.defineProperty

    class Mock {
      foo = 'bar'
    }
    const obj = new Mock()
    console.log(obj.foo)
    
    Object.defineProperty(obj, 'foo', {
      value: 'Something else',
      writable: true,
      enumerable: false,
      configurable: false
    })
    
    console.log(obj.foo)

【讨论】:

    猜你喜欢
    • 2017-10-20
    • 1970-01-01
    • 2016-11-13
    • 1970-01-01
    • 2019-07-06
    • 2017-12-06
    • 1970-01-01
    • 1970-01-01
    • 2016-04-20
    相关资源
    最近更新 更多