B.3.1 The __proto__ pseudo property

Andreas Rossberg rossberg at google.com
Tue Apr 23 02:00:39 PDT 2013


On 23 April 2013 05:11, Mark S. Miller <erights at google.com> wrote:
> The first two goals generally align well anyway. I think this is best served
> by something that seems at least close to what was agreed on:
>
> * The syntax that we've already agreed to on this thread: {__proto__: ....}
> is special syntax that initialized the [[Prototype]]. No need for anything
> even as mildly imperative as [[SetPrototype]].
>
> * { [ "__proto__" ]: .... } is not special in any way, and creates a normal
> property named "__proto__".
>
> * Every object with a potentially mutable [[Prototype]] must be identified
> with a realm of origin. (Practically this will be "any object", which is
> good because that is what Weak References will need anyway.)
>
> * In the initial state of a normal realm, Object.prototype.__proto__ is an
> accessor property with the descriptor (making up names for the internal
> functions -- don't take the names seriously):
>
> { getter: [[ProtoGetter]], setter: [[ProtoSetter]], enumerable: false,
> configurable: true }
>
> * In this initial state, Object.getOwnPropertyDescriptor(Object.prototype,
> '__proto__') returns the above descriptor. No magic.
>
> * In this initial state, Object.getOwnPropertyNames(Object.prototype)
> returns a list which includes the string "__proto__". No magic.
>
> * Likewise for all other reflective operations, including "in". No magic.
>
> * The behavior of [[ProtoGetter]] is approximately
>
>     function [[ProtoGetter]] () { return Object.getPrototypeOf(this); }
>
> except of course that it uses the internal function rather than the current
> binding of Object.getPrototypeOf. Just like Object.getPrototypeOf, this
> behavior is independent of Realm. It is also independent of whether
> [[ProtoGetter]] is invoked *as* an accessor or invoked otherwise, for
> example by using Function.prototype.call.
>
> * The behavior of [[ProtoSetter]] is approximately
>
>     function [[ProtoSetter]] (newValue) {
>         if ([[GetRealm]](this) !== [[GetRealm]]([[ProtoSetter]])) {
>             throw new TypeError(....); // or should this be RangeError ?
>         }
>         this.[[SetPrototype]](newValue);
>     }
>
> This behavior is independent of whether [[ProtoSetter]] is invoked *as* an
> accessor or invoked otherwise, for example by using Function.prototype.call.
>
> * Normal objects have a [[SetPrototype]] method like
>
>     function [[SetPrototype]] (newValue) {
>         // normal checks for proto acceptability
>         // * either null or an object
>         // * would not create an inheritance cycle
>         this.[[Prototype]] = newValue;
>     }

That matches my thinking exactly (modulo the fix in your follow-up).

/Andreas


More information about the es-discuss mailing list