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 <[email protected]> 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 < > [email protected]> 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 <[email protected]> wrote: >> >>> `Object.defineProperties(target, >>> Object.getOwnPropertyDescriptors(source))`? >>> >>> On Thu, Feb 13, 2020 at 2:24 AM Andrea Giammarchi < >>> [email protected]> 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 >>>> [email protected] >>>> https://mail.mozilla.org/listinfo/es-discuss >>>> >>>
_______________________________________________ es-discuss mailing list [email protected] https://mail.mozilla.org/listinfo/es-discuss

