A Precedent

# Andrea Giammarchi (12 years ago)

"a principle or rule established in a previous case": precedent

I should not be here and I will not answer, just my last attempt trying to make a point.

Please consider the main developer behind node.js agrees this property should never land in JS as it's a minefield game specially when security and server side stuff is involved.

Current status: gist.github.com/WebReflection/5370050

// all IE < 10 browsers

if (!('__proto__' in {})) {
  console.log('you gonna have hard time');
}

// all Mobile WebKit browsers

if ('__proto__' in Object.create(null)) {
  console.log('you gonna have hard time');
}

// all not so updated Chrome browsers plus many mobile  browsers

if (!Object.getOwnPropertyDescriptor(Object.prototype, '__proto__').configurable) {
  console.log('you gonna have hard time');
}

// all updated Chrome browsers plus current node.js

if (!Object.getOwnPropertyDescriptor(Object.prototype, '__proto__').set) {
  console.log('you gonna have hard time');
}

now ask yourself how good is for the web to promote early adoption of broken ideas so that the whole future of the language will get screwed.

I think it's called Butterfly Effect, and once again this is the best time ever to officially drop that property instead of promoting it!

P.S. all the community needed/wanted, wasn't a shame like that property in the Object.prototype but a way to subclass or swap class to native, untouchable, instances/constructors such NodeList and all non ArrayLike objects: nothing else, really!

Object.setPrototypeOf(obj, proto):obj is a way better answer for next JS

# gaz Heyes (12 years ago)

On 12 April 2013 09:01, Andrea Giammarchi <andrea.giammarchi at gmail.com>wrote:

// all Mobile WebKit browsers

if ('proto' in Object.create(null)) {

console.log('you gonna have hard time');

}

If this is true that means it breaks the *only *way of creating a secure lookup table.

# Alex Russell (12 years ago)

I should not be here and I will not answer, just my last attempt trying to make a point.

Lobbing messages onto lists without any intent to follow up seems to me like it puts this out of the realm of good-faith efforts to fix something you think is broken.

Please consider the main developer behind node.js agrees this property should never land in JS

Assuming "this property" is __proto__, that ship sailed in V8 a long ago and there's zero chance of it ever being removed. It they want to remove it, they can simply fork V8 or ask for a build flag for it.

now ask yourself how good is for the web to promote early adoption of broken ideas so that the whole future of the language will get screwed.

Early adoption is for early adopters; that is to say, people willing to take risks knowing they might not pay off. Standardizing things is a way to remove risks so a larger population can benefit. That there is implementation ambiguity is often desireable pre-standardization to ensure that only the early-adopters bite off features which might otherwise look enticing.

I think it's called Butterfly Effect, and once again this is the best time ever to officially drop that property instead of promoting it!

Again, the ship sailed.

# Andrea Giammarchi (12 years ago)

Alex, I wrote that with best intents. I have the incredible ability to transform any thread in a flame so for this mailing list sake is better, as I've written already, to be as far away as possible (I keep watching threads though).

I'll try to quickly answer:

@gaz, yes, dictionaries and lookup tables are problematic in current mobile webkit browsers. proto has the ability to change a null object.

@Alex

In current Chrome proto is configurable and can be deleted. What's missing is the ability to recycle the setter later on (the getter ain't needed, there's Object.getProottypeOf() to do that) Once we have that, this woul dbe possible: gist.github.com/WebReflection/5247136

AFAIK, Chromium might solve this soon so no need to fork it? code.google.com/p/v8/source/detail?r=14139

I understand early adopters and the fact is unfortunately in too many browsers now as de-facto mess due all problems described before but I don't understand the answer of TC39

defineGetter defineSetter lookupGetter lookupSetter

have been used and adopted by all browsers but IE for years and the right answer from TC39 has been deprecating these and proposing

Object.defineProperty(get/set) and Object.getOwnPropertyDescriptor()

It is still not too late to propose Object.setPrototypeOf(target, proto):target and keep the proto status deprecated 'cause I cannot believe many of us are waiting for Object.prototype.proto to be removable so that the problem will be solved at the root.

The Mobile Zepto argument is really weak too. In the whole Zepto library, and I believe in jQuery too, proto is present in two tiny chinks of code. WebReflection/zepto/commit/66d84a05f8460f00dcf62cb610c0f12f606eff03

I've proposed already the push for that change but it comes again to chickes or eggs:

"we would change if Object.setPrototypeOf() was specd, there's proto se we are good like this"

Performance is not an issue and the ability to change a property name or a single piece of code makes a library a good one because refactoring is really easy to do if the code is well organized and compact as most of the libraries are out there.

Being also proto soem dark magic nobody expect from a user input but always managed internally, there won't be logic side effect too if not the desire one: there are no situations where an object can be mutated by accident.

The Ship Hasn't Sailed Yet ... ES6 is still a draft, and if that means anything, it means it can be changed.

Object.mixin() is there too completely minimal and identical to a status Object.setPrototypeOf(target, proto):target could be.

ES6 should spec that every property in the Object.prototype should be configurable and propose better mechanism than one that could make interoperability even more problematic in case node.js decides to do not expose proto and the web keep relying in a broken already deprecated thing that will stay as it is for long time due not so new, and not so old, Android devices, Nokia, etc.

All the best

# Brendan Eich (12 years ago)

Andrea Giammarchi wrote:

Alex, I wrote that with best intents. I have the incredible ability to transform any thread in a flame so for this mailing list sake is better, as I've written already, to be as far away as possible (I keep watching threads though).

At least read up on the topic. A "site:mail.mozilla.org es-discuss __proto__ __defineGetter__" search is a good starting point.

esdiscuss/2013-March/029341

(a reply to you asking the same thing you again ask, in March -- did you not read the reply last month?)

This leads directly (at bottom) to

rwldrn/tc39-notes/blob/master/es6/2013-01/jan-29.md#45-why-standardizing-on-proto-and-not-definegsetter-_lookupgsetter

wherein Rick recorded:

4.5 Why standardizing on __proto__ and not __define(G|S)etter__, __lookup(G|S)etter__?

(Based on a recent es-discuss thread)

Why __proto__ normative mandatory in ES6 but no __define/lookup... is:

  1. __proto__ much more used on the mobile (iOS WebKit-first) web, no equivalent interop pressure for __d/l.
  2. ES5 is in all new/evergreen browsers and it has standard APIs supplanting __d/l but nothing for writing to __proto__.

Therefore __proto__ gets standardized, __d/l do not.

Rationale for not adding Object.setPrototypeOf esdiscuss/2012-May/022904

Conclusion/Resolution

Consensus that __define(G|S)etter__, __lookup(G|S)etter__ will not be standardized, nor added to an Appendix.

 

AFAIK, Chromium might solve this soon so no need to fork it? code.google.com/p/v8/source/detail?r=14139

No, because the setter will be poisoned, per

I understand early adopters and the fact is unfortunately in too many browsers now as de-facto mess due all problems described before but I don't understand the answer of TC39

  • __defineGetter__
  • __defineSetter__
  • __lookupGetter__
  • __lookupSetter__

have been used and adopted by all browsers but IE for years and the right answer from TC39 has been deprecating these and proposing

  • Object.defineProperty(get/set)

and

  • Object.getOwnPropertyDescriptor()

It is still not too late to propose Object.setPrototypeOf(target, proto):target and keep the __proto__ status deprecated 'cause I cannot believe many of us are waiting for Object.prototype.__proto__ to be removable so that the problem will be solved at the root.

We've been over this many times, as noted above often in direct replies to your posts.

Are you not reading the replies, or forgetting them?

/be

# Brendan Eich (12 years ago)

Brendan Eich wrote:

AFAIK, Chromium might solve this soon so no need to fork it? code.google.com/p/v8/source/detail?r=14139

No, because the setter will be poisoned, per

... esdiscuss/2013-February/028631

It looks like the setter throws only if called on an object from a different "realm", so maybe it will work for your intended uses. It won't work cross-frame, in other words.

# Andrea Giammarchi (12 years ago)

Adding Object.setPrototypeOf does not help, because code won't migrate to it completely so we'll be stuck with two APIs.

As shown in the first post we'll be stuck with 4 APIs plus the 5th one standardized.

The __proto__ that is not supported, the one that is wrongly inherited in Object.create(null), the non configurable, and the configurable without get/set

SES and similar subsets would be > unable to protect secure code from ambient Object.setPrototypeOf usage > from the insecure side on the secure side's objects, unless > Object.setPrototypeOf were removed -- but that would break insecure-side > code that reasonably (per your wishes) uses Object.setPrototypeOf in > lieu of proto.

same way SES can protect from __proto__ it can protect from Object.setPrototypeOf redefining in a way that who's white listed can obtain same result.

SES should not be that important to make decision for most web and server where SES is not the reality.

As summary, I do read answers, but I haven't ever seen one strong enough.

Refactoring __proto__ is 1 minute task for any library out there

SES uses with() and other things for its own purpose ... SES can deal with Object.setPrototypeOf

The API and the compatibility is broken regardless standardization.

Being a mess is the best moment to realize that instead of being trapped behind this mess we can drop it and as soon as Object.setPrototypeOf will appear in ES6 developers will change direction I believe without many problems.

The community writes shims and polyfill since 1999, I strongly doubt the easiest one ever would be so problematic.

# Brendan Eich (12 years ago)

Andrea Giammarchi wrote:

Adding Object.setPrototypeOf does not help, because code won't migrate to it completely so we'll be stuck with two APIs.

As shown in the first post we'll be stuck with 4 APIs plus the 5th one standardized.

What 4 APIs are you talking about?

The __proto__ that is not supported, the one that is wrongly inherited in Object.create(null), the non configurable, and the configurable without get/set

The old ones go away. We can't fix browsers in the field, you know that. Your argument is unfairly lumping changes we can make with ones we can't and counting them all against the ones we can make.

SES and similar subsets would be unable to protect secure code from ambient Object.setPrototypeOf usage from the insecure side on the secure side's objects, unless Object.setPrototypeOf were removed -- but that would break insecure-side code that reasonably (per your wishes) uses Object.setPrototypeOf in lieu of __proto__.

same way SES can protect from __proto__ it can protect from Object.setPrototypeOf redefining in a way that who's white listed can obtain same result.

No, same-frame mashups of SES and non-SES-that-uses-Object.setPrototypeOf cannot "whitelist" unless every SES object (or alternatively non-SES object) is put in a whitelist weak-set.

/be

# Andrea Giammarchi (12 years ago)

if you consider Object.setPrototypeOf an API and __proto__ another one then I consider all variants of __proto__ other APIs

As you said we cannot get rid of so standardizing an extra one on top will create 5 different scenarios.

Old __proto__ will go away, same could be for __proto__ if ES6 will propose only 1 API, Object.setPrototypeOf, which is new and then surely more consistent than any other version of __proto__ even with older browsers that supports __proto__ as non configurable and inherited in Object.create(null).

Bear in mind the only reason I am here again is that node.js might decide to drop __proto__ and without an alternative the server could miss a handy opportunity, for whoever needs it, to promote inheritance in existent objects.

# Brendan Eich (12 years ago)

if you consider Object.setPrototypeOf an API and __proto__ another one then I consider all variants of __proto__ other APIs

As I just wrote, this counting old pre-ES6 __proto__ variations is unfair because ES6 can't affect browsers in the field. Knock it off.

As you said we cannot get rid of so standardizing an extra one on top will create 5 different scenarios.

Old browsers die off. Stop evading my point. If you can't respond to it, then stop responding.

Old __proto__ will go away, same could be for __proto__ if ES6 will propose only 1 API,

No, because your hair-splitting over variations in old __proto__ semantics does not alter the fact that __proto__ works so well that Microsoft needs to support it to gain market share.

Hair-splitting about variations to inflate your count and make an added, de novo API that no one wants, which is an ambient capability on Object, is bad and it won't happen.

Object.setPrototypeOf, which is new and then surely more consistent than any other version of __proto__

No, it's misplaced and represents too much power in one place. The SES/non-SES mashup is just one example of this.

even with older browsers that supports __proto__ as non configurable and inherited in Object.create(null).

Bear in mind the only reason I am here again is that node.js might decide to drop __proto__ and without an alternative the server could miss a handy opportunity, for whoever needs it, to promote inheritance in existent objects.

Because @izs tweeted something you think Node is going to fork V8? Get real!

# Andrea Giammarchi (12 years ago)

he doesn't need to fork V8, he simply needs to delete Object.prototype.__proto__; at startup time so I am getting real.

# Brendan Eich (12 years ago)

Andrea Giammarchi wrote:

he doesn't need to fork V8, he simply needs to delete Object.prototype.proto;

I double-dog dare anyone to do this and keep all the NPM modules working.

There won't be a standard Object.setPrototypeOf.

Maybe it's time to stop the same runaround as last month, at least till next month?

# Andrea Giammarchi (12 years ago)

also, too much power because of a function instead of a hot/swap through a property?

who told you nobody wants that function because prefer __proto__ instead ?

Do you read internet where every developer calls __proto__ugly ?

And btw, which part I did not reply ... I have no idea, honestly!

# David Bruant (12 years ago)

Le 13/04/2013 03:31, Andrea Giammarchi a ?crit :

Do you read internet where every developer calls __proto__ ugly ?

I do read the Internet 1. I believe Brendan and all TC39 do too. Let's be super careful when using "every"/"all"/"no"/"none"/"always"/"never" and other superlatives.

History happened in the following order:

  1. Mobile was pretty much WebKit-based only (at least that's what some devs have taken it)
  2. Relevant WebKit-based browsers all have __proto__
  3. Content (like Zepto) started to make the assumption that web browsers do have __proto__.
  4. Content (like Zepto) got popular and this created an incentive for IE to support __proto__ 2 (among other things I imagine)
  5. Microsoft will certainly implement __proto__ no matter what. This is apparently confirmed by folks who studied the leaked IE11 3

The 5 points are facts (the last is an assumption, but a strong one). Now, given these facts, what are the choices left to TC39?

  1. Ignore reality. Hopefully, we will all agree that this would be plain irresponsible.
  2. Standardize __proto__

Andrea: I and probably everyone else is as frustrated as you are of __proto__ standardization. But the above 5-points history is what it is; sorry for the self-quote, but "Web technologies are ugly and there is no way back..." 4.

The only alternative to standardizing __proto__ is not standardizing it and it's a worse idea (because of interoperability issues that would arise). __proto__ is happening in ES6 not because people actively want it, but because it's better than any other alternatives.

As I've repeated multiple times on the list, a feature being part of the standard doesn't make it a legitimate feature that web developers should seek to use (to a large extent, Crockford with his "good parts" said the exact same thing).

I read not introducing setPrototypeOf also as a social/political move to say to devs "TC39 is aware __proto__ is an awful monster that we have to bring to the standard, but we do not consider it as a recommended feature". But the standard cannot document the history of features. It also is neutral on what should be used by devs.

It's up to us (JS devs), to decide which parts we promote and use and which parts we think are stupid in the language. It's not up to TC39 (though obviously they have their opinions).

Feel free to contribute to ECMAScript Regrets :-) It seems like a more appropriate place to rant about __proto__ and why it should be avoided by devs than es-discuss.

# Nathan Wall (12 years ago)

Brendan Eich wrote:

... esdiscuss/2013-February/028631

It looks like the setter throws only if called on an object from a different "realm", so maybe it will work for your intended uses. It won't work cross-frame, in other words.

Great! Will the setter be capable of setting the prototype on objects which don't inherit from Object.prototype (as long as they're in the same realm)? If so, that would allow me to work around the majority of my problems from 1. There are still some edge cases that couldn't be supported, but I'll be okay with that since they are really minor edge cases.

# Andrea Giammarchi (12 years ago)

at least in Firefox is working like that:

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

var NaO = Object.create(null);

var o = {};

blackMagic.call(NaO, o);

o.isPrototypeOf(NaO); // true

if this will work cross browser like this adopting a method rather than a property that who knows if it'se there or not seems to be a natural consequence, same way almost every library I know use

var hasOP = {}.hasOwnProperty

then hasOP.call(obj, prop) so even Object.create(null) can be checked like that