【问题标题】:es6 class with default property on prototype throws in traceur原型上具有默认属性的 es6 类在 traceur 中抛出
【发布时间】:2015-02-08 06:35:05
【问题描述】:

我最近开始使用 traceur,并在原型上创建具有默认值的类时偶然发现了一个奇怪的行为。我想知道这是 traceur 中的错误还是 ES6 类的预期行为?

class hasDefault {
  setValue ( v ) {
    this.v = v;
  }
}
Object.defineProperty( hasDefault.prototype, "v", {
  value : 5,
  enumerable : true
});

let a = new hasDefault;
console.assert(a.v === 5);
a.setValue(2);
console.assert(a.v === 2);

run in traceur REPL

当我尝试设置只读属性“v”时,它会引发我无法分配给它的错误。这没有意义,因为属性是在原型上定义的,而不是在实例上。此外,我无法在密封/冻结/不可扩展对象上抛出 es5 的错误,据我所知,代理没有在 V8 中实现,所以......它是如何首先抛出错误的?这不是编译时错误。

我的主要兴趣不是“让它发挥作用”,这是微不足道的。您需要做的就是将this.v = v 替换为Object.defineProperty 等效项。我主要想知道它是否以及为什么会以这种方式运行,以及此数据结构中是否存在负面性能影响,通过将默认属性分配给原型而不是将它们存储在每个实例上来超过内存​​增益。

【问题讨论】:

    标签: javascript ecmascript-6 traceur


    【解决方案1】:

    当我尝试设置只读属性“v”时,它会引发我无法分配给它的错误。这没有意义,因为属性是在原型上定义的,而不是在实例上。

    是的,该属性是只读的,因为 writable 属性默认为 false。并且当v 属性被继承时,该属性也对赋值有效。

    我也无法在 es5 中抛出该错误

    你只需要使用严格模式就可以了:

    "use strict";
    var test = Object.create(Object.defineProperty({}, "v", {value: 5, enumerable: true}));
    console.log(test.v) // 5
    test.v = 1; // Unhandled Error: Invalid assignment in strict mode
    

    【讨论】:

    • 啊,好的,谢谢,我不知道属性描述符在继承时会以这种方式工作,但它确实有意义。您对严格模式也是正确的,这对我来说很草率,在控制台中进行了测试并忘记了它:)
    【解决方案2】:

    如果您使用Object.defineProperty 定义属性,仅指定value 而不是getset,那么您使用的是data descriptor(请参阅here)。使用data descriptor,您可以添加writable 属性来指定是否可以更改属性。默认writable=false

    因此,如果您仅指定 value 的数据描述符,而不指定 writable: true - 您以后无法更改该属性。这种行为与 ES6 无关,因为 Object.defineProperty 是在 ES5 中引入的。

    正确代码:

    class hasDefault {
      setValue ( v ) {
        this.v = v;
      }
    }
    Object.defineProperty( hasDefault.prototype, "v", {
      value : 5,
      writable: true,
      enumerable : true
    });
    
    let a = new hasDefault;
    console.assert(a.v === 5);
    a.setValue(2);
    console.assert(a.v === 2);
    

    Traceur REPL

    【讨论】:

    • 谢谢,您的回答是正确的,但在我的情况下,混淆更多的是实例描述符的继承,而不是不可写属性本身。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-11
    • 1970-01-01
    • 1970-01-01
    • 2020-04-09
    • 1970-01-01
    • 2016-11-13
    相关资源
    最近更新 更多