Why are class getters/setters non-enumerable?

Logan Smyth loganfsmyth at gmail.com
Sat Oct 8 23:47:13 UTC 2016


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.




On Sat, Oct 8, 2016 at 4:14 PM, /#!/JoePea <joe at trusktr.io> wrote:

> I've ran into this bug due to non-enumerable accessors:
> https://github.com/tweenjs/tween.js/issues/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"...
>
> ```js
> 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}
> ```
>
>
> */#!/*JoePea
>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20161008/036d7912/attachment.html>


More information about the es-discuss mailing list