Any chance for an `Object.assignProperties` ?

Andrea Giammarchi andrea.giammarchi at gmail.com
Thu Feb 13 18:23:11 UTC 2020


That has nothing to do with this, right?

```js
const {assign, defineProperties, getOwnPropertyDescriptors} = Object;
const assignProperties = (base, ...mixins) => defineProperties(
  base,
  mixins.reduce(
    (descriptors, mixin) => assign(
      descriptors,
      getOwnPropertyDescriptors(mixin)
    ),
    {}
  )
);
```

On Thu, Feb 13, 2020 at 6:51 PM Jordan Harband <ljharb at gmail.com> wrote:

> `Object.defineProperties(target,
> Object.getOwnPropertyDescriptors(source))`?
>
> On Thu, Feb 13, 2020 at 2:24 AM Andrea Giammarchi <
> andrea.giammarchi at gmail.com> wrote:
>
>> 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
>> 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/20200213/4f560003/attachment.html>


More information about the es-discuss mailing list