Javascript traceur中原型上具有默认属性的es6类

Javascript traceur中原型上具有默认属性的es6类,javascript,ecmascript-6,traceur,Javascript,Ecmascript 6,Traceur,我最近开始使用traceur,在原型上创建带有默认值的类时,偶然发现了一个奇怪的行为。我想知道这是traceur中的一个bug,还是ES6类的预期行为 class hasDefault { setValue ( v ) { this.v = v; } } Object.defineProperty( hasDefault.prototype, "v", { value : 5, enumerable : true }); let a = new hasDefault;

我最近开始使用traceur,在原型上创建带有默认值的类时,偶然发现了一个奇怪的行为。我想知道这是traceur中的一个bug,还是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);

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


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

如果您使用
对象定义属性。defineProperty
仅指定
而不是
获取
设置
,然后使用
数据描述符
(请参阅)。使用
数据描述符
可以添加
可写
属性,以指定是否可以更改属性。默认情况下
writable=false

因此,如果只指定数据描述符的
,而不指定
可写:true
,则以后不能更改该属性。此行为与ES6无关,因为ES5中引入了
Object.defineProperty

正确代码:

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);

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

是,该属性是只读的,因为
可写
属性默认为
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

啊,好的,谢谢,我不知道继承时属性描述符是这样工作的,但它确实有意义。关于strict模式,您也是对的,这对我来说很草率,在控制台中进行了测试,但忘记了:)谢谢,您的回答是正确的,但在我的例子中,混淆更多的是实例描述符的继承,而不是不可写属性本身。