Both `Object.assign` and `{...extend}` suffer a tiny gotcha: properties are
never assigned, neither retrieved, as accessors, with side-effects too.
Example:
```js
const Counter = {
_count: 0,
get count() {
return this._count++;
}
};
const incr1 = Object.assign({}, Counter);
const incr2 = {...Counter};
console.log(
incr1.count, // 0
incr2.count, // 1
Counter._count // 2
);
// functionality also compromised
console.log(incr1.count === incr1.count);
```
Not only most of the time this is unexpected, but there's literally no way
to pass along accessors with a similar `Object.assign` ease, even if that's
what most developers would expect (at least up to the first time they
encounter above issue).
How about we introduce `Object.assignProperties` instead?
A polyfill example:
```js
const {assign, defineProperties, getOwnPropertyDescriptors} = Object;
const assignProperties = (base, ...mixins) => defineProperties(
base,
mixins.reduce(
(descriptors, mixin) => assign(
descriptors,
getOwnPropertyDescriptors(mixin)
),
{}
)
);
```
We can now use objects and mixins without side-effecting sources used to
extend, and preserving accessors in the process.
```js
const Counter = {
_count: 0,
get count() {
return this._count++;
}
};
const incr1 = Object.assignProperties({}, Counter);
const incr2 = Object.assignProperties({}, Counter);
console.log(
incr1.count, // 0
incr2.count, // 0
Counter._count // 0
);
// always false: preserved functionality
console.log(incr1.count === incr1.count);
```
Thoughts ?
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss