Jan 29 TC39 Meeting Notes
Claude Pache
claude.pache at gmail.com
Fri Feb 8 10:15:19 PST 2013
Le 8 févr. 2013 à 16:00, David Bruant <bruant.d at gmail.com> a écrit :
> Le 07/02/2013 18:42, Andreas Rossberg a écrit :
>> On 7 February 2013 18:36, David Bruant <bruant.d at gmail.com> wrote:
>>> I hardly understand the benefit of an inconditionally-throwing setter over a
>>> __proto__ as data property, but I'm fine with either.
>> Well, it _is_ a setter, and even one that modifies its receiver, not
>> its holder. What would be the benefit of pretending it's not?
> It _is_ an abomination (arguably, it even __is__ an abomination). Any resemblance to real ECMAScript construct, living or dead (?), is purely coincidental.
>
> From the notes, a quote from Allen is "involves magic". I don't think I will surprise anyone if I say that whatever is decided for __proto__, there will be magic involved.
>
> An idea that I don't think has been suggested is to stop pretending __proto__ is something else than magic:
> $> Object.getOwnPropertyDescriptor(Object.prototype, '__proto__');
> {
> magic: true,
> enumerable: false,
> configurable: true
> }
>
> Quite exotic but very clear. At will, replace "magic" with "abomination", "de facto standard", "wildcard", "don't use __proto__" or "Why did you call Object.getOwnPropertyDescriptor on __proto__ anyway?". Other better suggestions are welcome, obviously.
> Admittedly, the last idea may be a bit long, but that's a string, so that can be an property name. I wouldn't rule it out too quickly ;-)
>
> David
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
The magic is not in the form of the '__proto__' property of the Object.prototype object, but in the action that its setter performs. Precisely, as implemented in the latest versions of Safari and Firefox (I haven't tested other browsers), Object.prototype.__proto__ acts as if it has been defined as follows:
;(function() {
var getPrototypeOf = Object.getPrototypeOf
Object.defineProperty(Object.prototype, '__proto__', {
get: function() { return getPrototypeOf(this) }
, set: function(p) { __setPrototypeOf__(this, p) }
, configurable: true
, enumerable: false
})
})()
where __setPrototypeOf__(obj, p) is some function that does the following (note the second bullet):
* throws an error if obj is not an object; otherwise,
* throws an error if obj is not extensible; otherwise,
* fails if p is not an object; otherwise,
* throws an error if obj is equal to p or is in the prototype chain of p (to avoid cycles); otherwise,
* replaces the prototype of obj with p.
The only part not user-implementable (and the only magic, if any,) is in the "replaces the prototype of obj with p" part above.
However, I would find reasonable to treat __proto__ similarly to eval: so that the aforementioned __setPrototypeOf__ function is allowed to fail when it has not been called with the exact syntax obj.__proto__ = something. Anything else, including obj['__proto__'] = something, could fail. Admittedly, THAT would be black magic, but again, it is not in form the property descriptor, but in the definition of __setPrototypeOf__.
—Claude
More information about the es-discuss
mailing list