B.3.1 The __proto__ pseudo property

Andrea Giammarchi andrea.giammarchi at gmail.com
Sun Apr 21 14:11:16 PDT 2013


agreed for consistency too, once deleted, the magic should disappear 100%

reality will be that most devs won't delete it so I don't see concrete side
effects out there.

However, this is how I would spec it (or better, how I would drop the axe
accepting a compromise for this property)

Object.getOwnPropertyDescriptor(Object.prototype, '__proto__')
must return
{
  enumerable: false,
  configurable: true,
  get: function usableGetter(){},
  set: function usableSetter(){}
}

Being configurable anyone can decide to poison the setter, if necessary, or
trap it and get read of the magic.
It is not possible to have options if the setter is poisoned by default or
not exposed at all.
The magic can be preserved, if necessary, and reused.

"First come first serve" as same rule exists today if somebody wants, for
some reason,
Object.freeze(global);
or
Object.freeze(Object.prototype);
with all toString, etc consequences we know ... it worked 'till now,
libraries can evolve and/or agree on the expected surrounding environment.

Once deleted, the whole magic should disappear.
var o = {__proto__:null};

will be an instanceof Object with .hasOwnProperty('__proto__') true and
.propertyIsEnumerable('__proto__') true and o.__proto__ === null

In few words, once __proto__ has been deleted, that name means that's a
property name and nothing else.

I think this makes specs easy to define:
if not there, everything as it is for everything else

if there, define the property descriptor without adding any extra/special
case on it

This is the easiest way to go, this can make SES the same is today doing:

Object.defineProperty(
  Object.prototype,
  '__proto__',
  {
    get: Object.getOwnPropertyDescriptor(
      Object.prototype,
      '__proto__'
    ).get,
    set: function () {
      throw new Error('you are not supposes to do this');
    }
  }
);

This will make possible to create e single entry point for the magic and
monitor it:

var set = Object.getOwnPropertyDescriptor(
      Object.prototype,
      '__proto__'
    ).set;

delete Object.prototype.__proto__;

This will make whoever wants to do anything with this magic able to do it
and, accordingly, I believe a happy JavaScripter!

My 2 cents







On Sun, Apr 21, 2013 at 1:37 PM, Brendan Eich <brendan at mozilla.com> wrote:

> Allen Wirfs-Brock wrote:
>
>> On Apr 21, 2013, at 12:31 PM, Brendan Eich wrote:
>> >  You don't want that to affect object literals evaluated in the same
>> realm after such a deletion. Why not?
>>
>> Why should it?
>>
>
> ... because it did in ES5-conforming implementations that support
> __proto__ as a de-facto standard *and* allow delete
> Object.prototype.__proto__.
>
>
>     We already used the existence of {__proto__: whatever} got rid of<| as
>> declarative syntax for defining an object literal with a [[Prototype]]
>> other than object prototype.  Making {__proto__: whatever}  only work some
>> of the times means it isn't a reliable declarative syntax.
>>
>
> What?
>
> Mark insists on delete Object.prototype.__proto__ making the magic go
> away. (Summoning Mark.)
>
> Triangle died for several reasons, and I'm surprised to hear it here.
> Grinding an axe?
>
>
>     Why would we want to do that?  There is arguably a good motivation
>> wanting disable the ability to dynamically __proto__ modify arbitrary
>> pare-existing objects. But what is the motifacation for doing that on newly
>> created objects?
>>
>
> I will tag Mark in here, but first make my own move:
>
> Answer: because the clear way to implement this in ES5-conforming
> implementations that support __proto__ is to call [[Put]] not
> [[DefineOwnProperty]] if the name of the property being initialized in the
> object literal is '__proto__', and that's what engines implement.
>
> That makes a new de-facto standard, which you should not be wasting energy
> trying to break!
>
>
>  SpiderMonkey at least goes out of its way to do [[Set]] (let's call it)
>>> not [[DefineOwnProperty]] for 'o = {__proto__: 42}', so why wouldn't
>>> [[Set]] create a fresh property, seeing nothing on Object.prototype named
>>> '__proto__' with a setter to run?
>>>
>>
>> Because the semantics that says you can't use [[DefineOwnProperty]] may
>> say to go out of the way to do something else.
>>
>
> Too late, ES5+reality happened. You are now proposing to break the web, at
> the limit. JS implementors will not go for that, so you are wasting your
> time.
>
>
>     It my strawman spec. it says use [[SetInhertiance]] rather than
>> [[Put]].  Either is a special case semantics and [[SetInheritance]] is a
>> much more direct expression of the likely user intent.
>>
>
> Direct, schmirect.
>
> This is about compatibility and consistency, not what you can edit into a
> draft. Please reconsider. Must we put this on the next meeting's agenda?
>
> /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/20130421/09e3c9b6/attachment.html>


More information about the es-discuss mailing list