A Precedent
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.
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.
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
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.
(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:
__proto__
much more used on the mobile (iOS WebKit-first) web, no equivalent interop pressure for__d/l
.- 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/022904Conclusion/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 forObject.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 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.
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.
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 inObject.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, unlessObject.setPrototypeOf
were removed -- but that would break insecure-side code that reasonably (per your wishes) usesObject.setPrototypeOf
in lieu of__proto__
.same way SES can protect from
__proto__
it can protect fromObject.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
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.
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!
he doesn't need to fork V8, he simply needs to delete Object.prototype.__proto__;
at startup time so I am getting real.
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?
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!
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:
- Mobile was pretty much WebKit-based only (at least that's what some devs have taken it)
- Relevant WebKit-based browsers all have
__proto__
- Content (like Zepto) started to make the assumption that web browsers do have
__proto__
. - Content (like Zepto) got popular and this created an incentive for IE to support
__proto__
2 (among other things I imagine) - 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?
- Ignore reality. Hopefully, we will all agree that this would be plain irresponsible.
- 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.
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.
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
"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