Readdition of __proto__

Andrea Giammarchi andrea.giammarchi at gmail.com
Mon Oct 14 16:21:56 PDT 2013


my last memories on the topic are these:

```javascript

var obj = JSON.parse('{"__proto__":[]}');
obj instanceof Array; // false
obj.__proto__ instanceof Array; // true
// since the proto is a property, not a magic thing
obj.__proto__ = 123; // da hell will happen, only Allen knows ^_^

```

And since latter should simply set the property named `"__proto__"` as
value `123` I got confused with this dual way to deal with an object when
it comes from JSON world (then has a property defined as value, not the
inherited set/get from Object.prototype)

As summary, `JSON.parse` over `"__proto__"` is similar to:
```javascript

var o = {};
Object.defineProperty(o, '__proto__', {
  value: 123,
  enumerable: true,
  writable: true,
  configurable: true
});

```

Which means in such case the property `"__proto__"` will fail with such
object while `Object.setPrototypeOf` won't which is the reason I keep
suggesting the latest to make the intent explicit.

Not arguing or anything, just speaking out loudly my confusion with that
property as string part.

Best Regards



On Mon, Oct 14, 2013 at 2:28 PM, Brendan Eich <brendan at mozilla.com> wrote:

> I think you may have mixed up a few things:
>
> 1. JSON does not recognize '__proto__' per its unchanging spec, and so
> parsing that identifier makes an own data property.
>
> 2. var obj = {__proto__: proto}; is a special form, unlike any other
> identifier __proto__ as the literal property name does assign (set) not a
> define.
>
> 3. Annex B.2.2.1 defines an accessor on Object.prototype, which if
> unshadowed will be got or set when used by name on objects that actually
> delegate to Object.prototype. It's also delete-able (configurable),
> important for SES and the like.
>
> /be
>
>  Andrea Giammarchi <mailto:andrea.giammarchi@**gmail.com<andrea.giammarchi at gmail.com>
>> >
>> October 14, 2013 1:53 PM
>>
>>  `JSON` serialization <=  `JSON` parse
>>
>>
>>
>> Andrea Giammarchi <mailto:andrea.giammarchi@**gmail.com<andrea.giammarchi at gmail.com>
>> >
>> October 14, 2013 1:53 PM
>>
>> Then I might have confused what decided with `JSON` serialization where
>> `"__proto__"` will be a property and not a setter, neither a getter once
>> deserialized.
>>
>> Is this correct? Yeah, I remember that different accessors looked weird
>> to me too ... thanks for clarification.
>>
>> Best Regards
>>
>>
>>
>> Brendan Eich <mailto:brendan at mozilla.com>
>> October 14, 2013 1:43 PM
>>
>>
>> What you just wrote is not true of __proto__ in SpiderMonkey or other
>> engines I can test (V8, JSC).
>>
>> It also can't be true via ES6 Annex B, since obj[key] and obj.foo where
>> key = 'foo' both lookup prototype properties and will find
>> Object.prototype.foo.
>>
>> /be
>> ______________________________**_________________
>> es-discuss mailing list
>> es-discuss at mozilla.org
>> https://mail.mozilla.org/**listinfo/es-discuss<https://mail.mozilla.org/listinfo/es-discuss>
>>
>> Andrea Giammarchi <mailto:andrea.giammarchi@**gmail.com<andrea.giammarchi at gmail.com>
>> >
>> October 14, 2013 1:32 PM
>> I meant that IIRC `obj["__proto__"]` should not invoke that Annex B
>> specified getter (@Benjamin, Annex B is where you'll find everything
>> related indeed) but `obj.__proto__` will ... unless once again I've missed
>> some update.
>>
>> Yeah, I know that you link stuff, and glad you made some time for extra
>> clarification.
>>
>> Cheers
>>
>>
>>
>> Brendan Eich <mailto:brendan at mozilla.com>
>> October 14, 2013 1:22 PM
>>
>> Andrea Giammarchi wrote:
>>
>>> __Current Status__
>>>
>>
>> (Thanks for the dunders! :-P)
>>
>>  Instead of formalizing its form, ES6 accepted `Object.setPrototypeOf` as
>>> described in specs and decided to silently move beside, but still have in
>>> specs, the dunder `__proto__` form, fixing at least a couple of related
>>> gotchas so that:
>>>
>>>   * unless explicitly set as property, `__proto__` is a named property
>>> for every object that should not affect inheritance so that
>>> `obj["__proto__"]` or `obj[key]` where `key` is the string `"__proto__"`
>>> should not hot/swap the prototypal chain
>>>
>>
>> I'm not sure what you mean here, but first, __proto__ is not specified in
>> ES6 drafts as an own property. See
>>
>> http://people.mozilla.org/~**jorendorff/es6-draft.html#sec-**B.2.2.1<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-B.2.2.1>
>>
>>
>>   B.2.2.1
>>   <http://people.mozilla.org/%**7Ejorendorff/es6-draft.html#**
>> sec-object.prototype.__proto__<http://people.mozilla.org/%7Ejorendorff/es6-draft.html#sec-object.prototype.__proto__>
>> **>
>>
>>   Object.prototype.__proto__
>>
>> Object.prototype.__proto__ is an accessor property with attributes {
>> [[Enumerable]]: false, [[Configurable]]: true }. The [[Get]] and [[Set]]
>> attributes are defined as follows
>>
>>
>>   B.2.2.1.1
>>   <http://people.mozilla.org/%**7Ejorendorff/es6-draft.html#**
>> sec-get-object.prototype.__**proto__<http://people.mozilla.org/%7Ejorendorff/es6-draft.html#sec-get-object.prototype.__proto__>
>> >
>>
>>   get Object.prototype.__proto__
>>
>> The value of the [[Get]] attribute is a built-in function that requires
>> no arguments. It performs the following steps:
>>
>>  1. Let /O/ be the result of calling ToObject
>>     <http://people.mozilla.org/%**7Ejorendorff/es6-draft.html#**
>> sec-toobject<http://people.mozilla.org/%7Ejorendorff/es6-draft.html#sec-toobject>
>> >
>>     passing the *this* value as the argument.
>>  2. ReturnIfAbrupt
>>     <http://people.mozilla.org/%**7Ejorendorff/es6-draft.html#**
>> sec-returnifabrupt<http://people.mozilla.org/%7Ejorendorff/es6-draft.html#sec-returnifabrupt>
>> >(/O/).
>>  3. Return the result of calling the [[GetPrototypeOf]] internal
>>     method of /O/.
>>
>>
>>   B.2.2.1.2
>>   <http://people.mozilla.org/%**7Ejorendorff/es6-draft.html#**
>> sec-set-object.prototype.__**proto__<http://people.mozilla.org/%7Ejorendorff/es6-draft.html#sec-set-object.prototype.__proto__>
>> >
>>
>>   set Object.prototype.__proto__
>>
>> The value of the [[Set]] attribute is a built-in function that takes an
>> argument proto. It performs the following steps:
>>
>>  1. Let /O/ be CheckObjectCoercible
>>     <http://people.mozilla.org/%**7Ejorendorff/es6-draft.html#**
>> sec-checkobjectcoercible<http://people.mozilla.org/%7Ejorendorff/es6-draft.html#sec-checkobjectcoercible>
>> >(***this*
>>     value)/./
>>  2. ReturnIfAbrupt
>>     <http://people.mozilla.org/%**7Ejorendorff/es6-draft.html#**
>> sec-returnifabrupt<http://people.mozilla.org/%7Ejorendorff/es6-draft.html#sec-returnifabrupt>
>> >(/O/).
>>  3. If Type
>>     <http://people.mozilla.org/%**7Ejorendorff/es6-draft.html#**
>> sec-ecmascript-data-types-and-**values<http://people.mozilla.org/%7Ejorendorff/es6-draft.html#sec-ecmascript-data-types-and-values>
>> >(/proto/)
>>     is neither Object or Null, then return /proto/.
>>  4. If Type
>>     <http://people.mozilla.org/%**7Ejorendorff/es6-draft.html#**
>> sec-ecmascript-data-types-and-**values<http://people.mozilla.org/%7Ejorendorff/es6-draft.html#sec-ecmascript-data-types-and-values>
>> >(/O)/
>>     is not Object, then return /proto/.
>>  5. Let /status/ be the result of calling the [[SetPrototypeOf]]
>>     internal method of /O/ with argument /proto/.
>>  6. ReturnIfAbrupt
>>     <http://people.mozilla.org/%**7Ejorendorff/es6-draft.html#**
>> sec-returnifabrupt<http://people.mozilla.org/%7Ejorendorff/es6-draft.html#sec-returnifabrupt>
>> >(/status/).
>>  7. If /status/ is *false*, then throw a *TypeError* exception.
>>  8. Return /proto/.
>>
>>
>>
>> /be
>>
>> ______________________________**_________________
>> es-discuss mailing list
>> es-discuss at mozilla.org
>> https://mail.mozilla.org/**listinfo/es-discuss<https://mail.mozilla.org/listinfo/es-discuss>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20131014/d1396bf8/attachment.html>


More information about the es-discuss mailing list