Search code examples
javascriptecmascript-6traceur

es6 class with default property on prototype throws in traceur


I recently started using traceur and stumbled upon an odd behavior when creating a class with default values on the prototype. I want to know if is this a bug in traceur or is this the intended behavior for ES6 classes?

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

It throws an error that I can't assign to the read only property "v" when I try to set it. Which doesn't make sense as the property is defined on the prototype, not the instance. Also I'm unable to get that Error to throw in es5 on sealed/frozen/non-extensible objects and as far as I know Proxies aren't implemented in V8, so... how does it throw the error in the first place? It's not a compile-time error.

My main interest isn't to "make it work", which is trivial. All you need to do is replace this.v = v by the Object.defineProperty equivalent. I primarily want to know if and why it behaves this way and if there are negative performance implications in this data structure that outweigh the memory gain by assigning default properties to the prototype instead of storing them on every instance.


Solution

  • It throws an error that I can't assign to the read only property "v" when I try to set it. Which doesn't make sense as the property is defined on the prototype, not the instance.

    Yes, the property is read-only as the writable attribute defaulted to false. And when the v property is inherited, this attribute is also in effect for assignments.

    Also I'm unable to get that Error to throw in es5

    You just have to use strict mode and it'll do:

    "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