Object.assign and __proto__ property

Rick Waldron waldron.rick at gmail.com
Mon Oct 21 19:55:24 PDT 2013


On Mon, Oct 21, 2013 at 10:28 PM, Nathan Wall <nathan.wall at live.com> wrote:

> > Allen Wirfs-Brock wrote:
> > Actually, this is a good point. As currently specified Object.assign
> > of with an own __proto__ property on the RHS object will trigger a
> > [[SetPrototypeOf]] on the LHS object. Is that what we want. It is a
> > direct fallout of specifying Object.assign as the equivalent of a
> > sequence of property assignments from the RHS to the LHS. "__proto__"
> > could be special cased. But should it?
> >
> > Object.mixin doesn't have this issue because, as Rick points out, it
> > uses GetOwnProperty/DefineProperty instead of Get/Set.
> >
> > Anybody want to argue that Object.assign shouldn't trigger
> > [[SetPrototypeOf]]?
> >
> > Allen
>
> Given that `__proto__` is defined as an accessor on `Object.prototype`, I
> think this should be expected. Any other setter defined on the object or
> its prototype chain will be invoked in the same manner. It's directly
> triggering `[[SetPrototypeOf]]`, it's just invoking the `__proto__` setter
> which happens to trigger `[[SetPrototypeOf]]`. Any number of accessor
> properties could do weird things:
>
>     Object.defineProperty(Object.prototype, 'bloikle', {
>         set(value) { Object.freeze(this); }
>     });
>
>     // Somewhere else far off in the code...
>     Object.assign(foo, { bloikle: 'bar' });
>
>     // Now foo is strangely frozen...
>

> For consistency, `__proto__` shouldn't be hidden from `Object.assign`.
>

Agreed.


> Plus, there's no reason this shouldn't work:
>
>     var info = JSON.stringify(
>         '{ "__proto__": "A description of __proto__",' +
>         '"hasOwnProperty": "A description of hasOwnProperty" }'
>     );
>
>     var otherInfo = JSON.stringify(
>         '{ "propertyIsEnumerable": "A description of propertyIsEnumerable"
> }'
>     );
>
>     Object.assign(otherInfo, info);
>     console.log(info.__proto__);
>
> Exploring other options.. A possible alternative consistent option would
> be to expose some mechanism to hide properties from `Object.assign`, so
> that the bloikle property could be hidden in the above... Doing this well
> would probably require a way to make it work cross-realm, which at first
> thought sounds pretty difficult. And it probably wouldn't play nice with
> the above `info` example.
>
> I think I agree with Andrea on this.  Should `Object.assign` be left out
> of ES6 for libraries to implement?


The point of adding Object.assign in ES6 was to pave the wide and heavily
trodden cowpaths that exist in libraries. As a built-in, the implementation
can be optimized in ways that would not be possible in library code.

... especially given that this `__proto__` dilemma feels "messy".
>

The very last comment seems subjective, and my own subjective response is
that it's not "messy".

Rick
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20131021/583c06cb/attachment.html>


More information about the es-discuss mailing list