<div><div dir="auto">It seems like it’s the exact implementation you want, just for 1 object instead of N.</div></div><div dir="auto"><br></div><div dir="auto">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?</div><div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Feb 13, 2020 at 10:23 AM Andrea Giammarchi <<a href="mailto:andrea.giammarchi@gmail.com">andrea.giammarchi@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>That has nothing to do with this, right?</div></div><div dir="ltr"><div><br></div><div><div>```js</div><div>const {assign, defineProperties, getOwnPropertyDescriptors} = Object;<br>const assignProperties = (base, ...mixins) => defineProperties(<br>  base,<br>  mixins.reduce(<br>    (descriptors, mixin) => assign(<br>      descriptors,<br>      getOwnPropertyDescriptors(mixin)<br>    ),<br>    {}<br>  )<br>);<br></div><div>```</div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Feb 13, 2020 at 6:51 PM Jordan Harband <<a href="mailto:ljharb@gmail.com" target="_blank">ljharb@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">`Object.defineProperties(target, Object.getOwnPropertyDescriptors(source))`?</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Feb 13, 2020 at 2:24 AM Andrea Giammarchi <<a href="mailto:andrea.giammarchi@gmail.com" target="_blank">andrea.giammarchi@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>Both `Object.assign` and `{...extend}` suffer a tiny gotcha: properties are never assigned, neither retrieved, as accessors, with side-effects too.</div><div><br></div><div>Example:<br></div><div>```js<br>const Counter = {<br>  _count: 0,<br>  get count() {<br>    return this._count++;<br>  }<br>};<br><br>const incr1 = Object.assign({}, Counter);<br>const incr2 = {...Counter};<br><br>console.log(<br>  incr1.count,    // 0<br>  incr2.count,    // 1<br>  Counter._count  // 2<br>);</div><div><br></div><div>// functionality also compromised<br></div><div>console.log(incr1.count === incr1.count);<br></div><div>```<br></div><div><br></div><div>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).</div><div><br></div><div>How about we introduce `Object.assignProperties` instead?</div><div><br></div><div>A polyfill example:<br></div><div><br></div><div>```js</div><div>const {assign, defineProperties, getOwnPropertyDescriptors} = Object;<br>const assignProperties = (base, ...mixins) => defineProperties(<br>  base,<br>  mixins.reduce(<br>    (descriptors, mixin) => assign(<br>      descriptors,<br>      getOwnPropertyDescriptors(mixin)<br>    ),<br>    {}<br>  )<br>);<br></div><div>```</div><div><br></div><div>We can now use objects and mixins without side-effecting sources used to extend, and preserving accessors in the process.</div><div><br></div><div>```js<br>const Counter = {<br>  _count: 0,<br>  get count() {<br>    return this._count++;<br>  }<br>};<br><br>const incr1 = Object.assignProperties({}, Counter);<br>const incr2 = Object.assignProperties({}, Counter);<br><br>console.log(<br>  incr1.count,    // 0<br>  incr2.count,    // 0<br>  Counter._count  // 0<br>);<br><br>// always false: preserved functionality<br>console.log(incr1.count === incr1.count);</div><div>```<br></div><div><br></div><div>Thoughts ?<br></div></div>
_______________________________________________<br>
es-discuss mailing list<br>
<a href="mailto:es-discuss@mozilla.org" target="_blank">es-discuss@mozilla.org</a><br>
<a href="https://mail.mozilla.org/listinfo/es-discuss" rel="noreferrer" target="_blank">https://mail.mozilla.org/listinfo/es-discuss</a><br>
</blockquote></div>
</blockquote></div>
</blockquote></div></div>