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