Why are class getters/setters non-enumerable?
FYI,
const xDesc = Object.getOwnPropertyDescriptor(XYZValues.prototype, 'x')
xDesc.enumerable = true
Object.defineProperty(XYZValues.prototype, 'x', xDesc)
const yDesc = Object.getOwnPropertyDescriptor(XYZValues.prototype, 'y')
yDesc.enumerable = true
Object.defineProperty(XYZValues.prototype, 'y', yDesc)
const zDesc = Object.getOwnPropertyDescriptor(XYZValues.prototype, 'z')
zDesc.enumerable = true
Object.defineProperty(XYZValues.prototype, 'z', zDesc)
can be done with
Object.defineProperty(XYZValues.prototype, 'x', {enumerable: true})
Object.defineProperty(XYZValues.prototype, 'y', {enumerable: true})
Object.defineProperty(XYZValues.prototype, 'z', {enumerable: true})
or even
['x', 'y', 'z'].forEach(prop => Object.defineProperty(XYZValues.prototype,
prop, {enumerable: true}))
Why are accessors non-enumerable when (to end user who use the properties
to access values) they are used in the exact same way that "properties" are? It seems that they should be enumerable because whether or not they are "accessors" is not the end user's concern, they merely access the "property"
Even if they were enumerable, there are still differences. The properties
aren't own
properties for instance, they exist on the class prototype,
not on the instance itself. You'd run into similar problems with any
library that doesn't traverse beyond own
keys, like Object.assign
, even
with enumerability.
To me, your assertion that they are supposed to be interchangeable is the problem. If they need to be a perfect replacement for standard data properties in the constructor, your best bet would be to define them in the constructor as enumerable own getter/setter properties just like the data properties would have been.
I've ran into this bug due to non-enumerable accessors: tweenjs/tween.js#267
The problem is that Tween.js does not detect the getters/setters in a for..in loop.
The solution I came up with is ugly, re-defining the descriptors to be enumerable, as demonstrated below. Is there a better way? Why are accessors non-enumerable when (to end user who use the properties to access values) they are used in the exact same way that "properties" are? It seems that they should be enumerable because whether or not they are "accessors" is not the end user's concern, they merely access the "property"...
class XYZValues { constructor(x = 0, y = 0, z = 0) { this._x = x this._y = y this._z = z } onChanged() {} set x(value) { this._x = value this.onChanged() } get x() { return this._x } set y(value) { this._y = value this.onChanged() } get y() { return this._y } set z(value) { this._z = value this.onChanged() } get z() { return this._z } } const xDesc = Object.getOwnPropertyDescriptor(XYZValues.prototype, 'x') xDesc.enumerable = true Object.defineProperty(XYZValues.prototype, 'x', xDesc) const yDesc = Object.getOwnPropertyDescriptor(XYZValues.prototype, 'y') yDesc.enumerable = true Object.defineProperty(XYZValues.prototype, 'y', yDesc) const zDesc = Object.getOwnPropertyDescriptor(XYZValues.prototype, 'z') zDesc.enumerable = true Object.defineProperty(XYZValues.prototype, 'z', zDesc) export {XYZValues as default}