es6类,在traceur中的原型上有默认属性

时间:2015-02-08 06:35:06

标签: javascript ecmascript-6 traceur

我最近开始使用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。我主要想知道它是否以及为什么会以这种方式运行,并且如果在这个数据结构中存在负面的性能影响,则通过将默认属性分配给原型而不是将它们存储在每个实例上来超过内存​​增益。

2 个答案:

答案 0 :(得分:1)

如果您使用仅Object.defineProperty而不是valueget的{​​{1}}定义属性,那么您使用的是set(请参阅here )。使用data descriptor,您可以添加data descriptor属性以指定是否可以更改属性。默认情况下为writable

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

正确的代码:

Object.defineProperty

Traceur REPL

答案 1 :(得分: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