Any chance for an `Object.assignProperties` ?

Andrea Giammarchi andrea.giammarchi at gmail.com
Thu Feb 13 19:50:55 UTC 2020


Anyway, if anyone is interested, I've published the `assign-properties`
module [1]

[1] https://github.com/WebReflection/assign-properties#readme

On Thu, Feb 13, 2020 at 7:51 PM Andrea Giammarchi <
andrea.giammarchi at gmail.com> wrote:

> The fact `assign` doesn't copy descriptors and has potential side-effects
> is documented extensively though, meaning there is room for improvement, or
> simply a missing native way to do that, like it was for
> `getOwnPropertyDescriptors`, that following your logic should've never
> landed.
>
> But I guess I'd go with the usual "yet another micro library" approach
> instead, so that at least I won't have to deal with assign shenanigans when
> I mean to copy accessors too.
>
> On Thu, Feb 13, 2020 at 7:33 PM Jordan Harband <ljharb at gmail.com> wrote:
>
>> It seems like it’s the exact implementation you want, just for 1 object
>> instead of N.
>>
>> Object.assign was added because versions of it were all over the web,
>> used very frequently. How frequent is the pattern where people want to copy
>> descriptors, such that it would deserve reification in the language?
>>
>> On Thu, Feb 13, 2020 at 10:23 AM Andrea Giammarchi <
>> andrea.giammarchi at gmail.com> wrote:
>>
>>> 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/692c0bcf/attachment-0001.html>


More information about the es-discuss mailing list