【问题标题】:Anything wrong with Object.freeze() on a JavaScript prototype?JavaScript 原型上的 Object.freeze() 有什么问题吗?
【发布时间】:2017-01-30 11:11:32
【问题描述】:

在 JavaScript 中对构造函数的原型调用 Object.freeze 有什么问题吗?

我只是在想,由于原型在所有实例之间共享,也许我可以通过冻结它来确保没有人覆盖原型中的任何内容,因为覆盖原型上的某些内容会影响每个实例。例如,如下所示:

function MyConstructor() {
  // Stuff
}

MyConstructor.prototype = {
  method1() {
    // more stuff
  },
  method2() {
    // even more stuff
  },
  someArray: ['some', 'values'],
  someValue: 'value'
}

Object.freeze(MyConstructor.prototype);

【问题讨论】:

    标签: javascript object prototype


    【解决方案1】:

    如果您冻结原型,您也会冻结扩展它的对象,因此它们将无法覆盖原型中定义的那些属性

    这个gist是一个展示问题的测试

    【讨论】:

    • 是的,您不能简单地分配给这些属性。但是不,继承对象没有被冻结,您仍然可以使用Object.defineProperty 创建阴影属性。
    • 没错,但关键是当原型在其他地方使用时冻结原型会导致各种问题。当然,除非您事先相应地计划。
    • @Bergi 你如何“冻结”原型而不影响从它“扩展”的对象?我希望从它“扩展”的对象在没有defineProperty 的情况下仍然可以轻松地隐藏原型,但是不允许修改原型本身。在这种情况下我们是否必须手动设置描述符(例如可配置/可写为 false)?
    • @trusktr 您可能会使用 getters/setters 而不是将 writable 设置为 false 来完成此操作。
    • @Bergi 我想禁止直接写入原型,但允许写入“扩展”对象(让它们隐藏原型)。这只能通过代理实现,还是有其他方法?我不知道用户将定义什么属性,因此对于 getter/setter,我必须在将非 getter/setter 属性转换为 getter/setter 后保留一个单独的 WeakMap 来保存值。似乎它可能过于复杂。
    【解决方案2】:

    我想你真正想要的是

    MyConstructor.prototype.someArray = Object.freeze(['some', 'values']);
    

    冻结原型对象本身几乎没有意义,没有什么会意外覆盖原型属性。然而,使继承的 不可变可能很有用,因为意外突变更容易发生并导致同样的不利影响。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-05
      • 2022-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多