Re: Readdition of __proto__
yeah, if you use an alias L the footgun image comes upside down too ``` L.__proto__ = null; // later on, in ES6 L.__proto__ = () pew, pew; ``` On Tue, Oct 15, 2013 at 11:01 PM, Brendan Eich bren...@mozilla.com wrote: Allen Wirfs-Brock wrote: On Oct 15, 2013, at 3:19 PM, Dean Landolt wrote: So just to be clear, the only way to add a __proto__ property to an existing object is with Object.defineProperty? Object.mixin(obj, {[__proto__]:42}); Allen Don't forget this chestnut: js var o = {} js o.__proto__ = null null js o.__proto__ = 42 42 js o.toString js /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Readdition of __proto__
On Mon, Oct 14, 2013 at 8:32 PM, Allen Wirfs-Brock al...@wirfs-brock.comwrote: On Oct 14, 2013, at 4:21 PM, Andrea Giammarchi wrote: my last memories on the topic are these: ```javascript var obj = JSON.parse('{__proto__:[]}'); obj instanceof Array; // false obj.__proto__ instanceof Array; // true // since the proto is a property, not a magic thing obj.__proto__ = 123; // da hell will happen, only Allen knows ^_^ ``` And since latter should simply set the property named `__proto__` as value `123` I got confused with this dual way to deal with an object when it comes from JSON world (then has a property defined as value, not the inherited set/get from Object.prototype) As summary, `JSON.parse` over `__proto__` is similar to: ```javascript var o = {}; Object.defineProperty(o, '__proto__', { value: 123, enumerable: true, writable: true, configurable: true }); ``` Which means in such case the property `__proto__` will fail with such object while `Object.setPrototypeOf` won't which is the reason I keep suggesting the latest to make the intent explicit. Not arguing or anything, just speaking out loudly my confusion with that property as string part. I think you are over thinking this: Assuming that Annex B.2.2.1 and B.3.1 are implemented: here are the cases of interest: let o1 = {__proto__: p}; // o1 inherits from p let o2 = {__proto__: p}; // o2 inherits from p let o3 = {[__proto__]: p};// o3 inherits from Object.prototype, has own data property __proto__ whose value is p. let o4 = JSON.parse('{__proto__: value}'); //o4 inherits from Object.prototype, has own data property __proto__ whose value is value //assuming that Object.prototype.__proto__ has not been tamper with: let o5 = new Object; o5.__proto__ = p ; //o5 inherits from p let o6 =new Object; o6[__proto__] = p; //o6 inherits from p There seems to be an interesting case missing: let attr = __proto__; let o7 = new Object; o7[attr] = p; // is this like o3? ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Readdition of __proto__
Not resolving this like o3 (or o6 really) sounds very strange. I think: let attr = __proto__; let o7 = new Object; o7[attr] = p; // o7 inherits from p Is the correct behavior here (why would it not invoke the setter?) On Wed, Oct 16, 2013 at 12:04 AM, Dean Landolt d...@deanlandolt.com wrote: On Mon, Oct 14, 2013 at 8:32 PM, Allen Wirfs-Brock al...@wirfs-brock.comwrote: On Oct 14, 2013, at 4:21 PM, Andrea Giammarchi wrote: my last memories on the topic are these: ```javascript var obj = JSON.parse('{__proto__:[]}'); obj instanceof Array; // false obj.__proto__ instanceof Array; // true // since the proto is a property, not a magic thing obj.__proto__ = 123; // da hell will happen, only Allen knows ^_^ ``` And since latter should simply set the property named `__proto__` as value `123` I got confused with this dual way to deal with an object when it comes from JSON world (then has a property defined as value, not the inherited set/get from Object.prototype) As summary, `JSON.parse` over `__proto__` is similar to: ```javascript var o = {}; Object.defineProperty(o, '__proto__', { value: 123, enumerable: true, writable: true, configurable: true }); ``` Which means in such case the property `__proto__` will fail with such object while `Object.setPrototypeOf` won't which is the reason I keep suggesting the latest to make the intent explicit. Not arguing or anything, just speaking out loudly my confusion with that property as string part. I think you are over thinking this: Assuming that Annex B.2.2.1 and B.3.1 are implemented: here are the cases of interest: let o1 = {__proto__: p}; // o1 inherits from p let o2 = {__proto__: p}; // o2 inherits from p let o3 = {[__proto__]: p};// o3 inherits from Object.prototype, has own data property __proto__ whose value is p. let o4 = JSON.parse('{__proto__: value}'); //o4 inherits from Object.prototype, has own data property __proto__ whose value is value //assuming that Object.prototype.__proto__ has not been tamper with: let o5 = new Object; o5.__proto__ = p ; //o5 inherits from p let o6 =new Object; o6[__proto__] = p; //o6 inherits from p There seems to be an interesting case missing: let attr = __proto__; let o7 = new Object; o7[attr] = p; // is this like o3? ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Readdition of __proto__
On Oct 15, 2013, at 2:10 PM, Benjamin (Inglor) Gruenbaum wrote: Not resolving this like o3 (or o6 really) sounds very strange. I think: let attr = __proto__; let o7 = new Object; o7[attr] = p; // o7 inherits from p Is the correct behavior here (why would it not invoke the setter?) This case is exactly the same as O6. Perhaps I should have written O6 as: o6[ (__proto__) ] = p; //o6 inherits from p to make that clearer. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Readdition of __proto__
Benjamin (Inglor) Gruenbaum wrote: Not resolving this like o3 (or o6 really) sounds very strange. I think: let attr = __proto__; let o7 = new Object; o7[attr] = p; // o7 inherits from p Is the correct behavior here (why would it not invoke the setter?) Allen confirmed, but just to be clear, any world where o[foo] and do { let key = foo; o[key]; } (do-expression syntax from harmony-era strawman) differ is crazytown, and we do not go there. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Readdition of __proto__
On Tue, Oct 15, 2013 at 5:50 PM, Brendan Eich bren...@mozilla.com wrote: Benjamin (Inglor) Gruenbaum wrote: Not resolving this like o3 (or o6 really) sounds very strange. I think: let attr = __proto__; let o7 = new Object; o7[attr] = p; // o7 inherits from p Is the correct behavior here (why would it not invoke the setter?) Allen confirmed, but just to be clear, any world where o[foo] and do { let key = foo; o[key]; } (do-expression syntax from harmony-era strawman) differ is crazytown, and we do not go there. True, but the __proto__ train left the station bound for crazytown long ago... So just to be clear, the only way to add a __proto__ property to an existing object is with Object.defineProperty? ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Readdition of __proto__
On Oct 15, 2013, at 3:19 PM, Dean Landolt wrote: So just to be clear, the only way to add a __proto__ property to an existing object is with Object.defineProperty? Object.mixin(obj, {[__proto__]:42}); Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Readdition of __proto__
not if you parsed that object via `JSON.parse('{__proto__:[]}')` in this case is the equivalent of that operation through `Object.defineProperty({}, '__proto__', {enumerable: true, writable: true, configurable: true})` so that `obj.__proto__` will result into property assignment and no setter invoked. ```javascript var o = JSON.parse('{__proto__:[]}'); o.__proto__ = Date.prototype; o instanceof Date;// false o.getTime === void 0; // true delete o.__proto__; // true // once again o.__proto__ = Date.prototype; // but this time ... o instanceof Date;// true o.getTime;// function[native] ``` Cheers On Tue, Oct 15, 2013 at 3:19 PM, Dean Landolt d...@deanlandolt.com wrote: On Tue, Oct 15, 2013 at 5:50 PM, Brendan Eich bren...@mozilla.com wrote: Benjamin (Inglor) Gruenbaum wrote: Not resolving this like o3 (or o6 really) sounds very strange. I think: let attr = __proto__; let o7 = new Object; o7[attr] = p; // o7 inherits from p Is the correct behavior here (why would it not invoke the setter?) Allen confirmed, but just to be clear, any world where o[foo] and do { let key = foo; o[key]; } (do-expression syntax from harmony-era strawman) differ is crazytown, and we do not go there. True, but the __proto__ train left the station bound for crazytown long ago... So just to be clear, the only way to add a __proto__ property to an existing object is with Object.defineProperty? ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Readdition of __proto__
oh, that's cute :D too bad I cannot shim/polyfill that in my `Object.mixin` module. I would simply *red-flag* it and discourage the usage of `__proto__` everywhere is possible (uhm wait ... I've already done that in the past, never mind ... ) Happy `__dunder__` Everybody, Cheers On Tue, Oct 15, 2013 at 4:03 PM, Allen Wirfs-Brock al...@wirfs-brock.comwrote: On Oct 15, 2013, at 3:19 PM, Dean Landolt wrote: So just to be clear, the only way to add a __proto__ property to an existing object is with Object.defineProperty? Object.mixin(obj, {[__proto__]:42}); Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Readdition of __proto__
To search es-discuss, I use site:mail.mozilla.org es-discuss as first two terms in a Google search. Sometimes I just use es-discuss. If you add __proto__ you'll find lots to read. Add meeting notes and you'll find recorded TC39 decisions. I usually find links and include them here to avoid just saying do your own search, but I'm short on time, sorry! /be Benjamin (Inglor) Gruenbaum mailto:ing...@gmail.com October 14, 2013 12:51 PM Let me start by apologizing for adding noise to the list. I looked for discussion of the standardization of __proto__ in the ES6 spec and couldn't find any. This is probably my shortcoming but I didn't know where to look or how to search the mailing list. I found a lot of threads discussing possible problems with Object.create(null) and __proto__ but not the discussion and decision to include it in the spec and to tell browser vendors to implement it. And then Branden's famous reply where he says he thinks it's a horrible idea :) Frankly, when I heard a while back it was introduced it surprised me (why would objects suddenly change their prototype?) I'm really interested in hearing the arguments and counter-arguments for/against it. Thanks again and sorry. Benjamin Gruenabum. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Readdition of __proto__
Thanks. Found a bunch of interesting things. Hopefully I'll find some use case where it doesn't completely break the beautiful OOP behavioral typing gives us when we play nice with it (Yep, that dog of yours, he's no longer an animal) :) On Mon, Oct 14, 2013 at 11:10 PM, Brendan Eich bren...@mozilla.com wrote: To search es-discuss, I use site:mail.mozilla.org es-discuss as first two terms in a Google search. Sometimes I just use es-discuss. If you add __proto__ you'll find lots to read. Add meeting notes and you'll find recorded TC39 decisions. I usually find links and include them here to avoid just saying do your own search, but I'm short on time, sorry! /be Benjamin (Inglor) Gruenbaum mailto:ing...@gmail.com October 14, 2013 12:51 PM Let me start by apologizing for adding noise to the list. I looked for discussion of the standardization of __proto__ in the ES6 spec and couldn't find any. This is probably my shortcoming but I didn't know where to look or how to search the mailing list. I found a lot of threads discussing possible problems with Object.create(null) and __proto__ but not the discussion and decision to include it in the spec and to tell browser vendors to implement it. And then Branden's famous reply where he says he thinks it's a horrible idea :) Frankly, when I heard a while back it was introduced it surprised me (why would objects suddenly change their prototype?) I'm really interested in hearing the arguments and counter-arguments for/against it. Thanks again and sorry. Benjamin Gruenabum. __**_ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/**listinfo/es-discusshttps://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Readdition of __proto__
Yes, it's hard to search in this mailing list but luckily not everyone in here will tell you not to be that guy that clearly didn't read anything and is just annoying ^_^ Since I've personally pushed to drop `__proto__` I might be the right person to give you pros and cons. Feel free to ask me more, if necessary (off-topic: the double underscore to talk about dunder proto is a hilarious must) __Pros__ * some library early adopted `__proto__` and few others followed making a _de facto used_ approach to easily hot/swap inehritance * it's widely available across all mobile and modern desktop browsers * it's faster than `Array.prototype.slice.call(genericCollection)` which is the unique place where Zepto library, probably the main reason dunder is still here, decided to swap `querySelectorAll` results ignoring incompatibility with IE Mobile at that time not so popular (then, one of the reason IE11 wanted to adopt it) __Cons__ * due lack of proper specs, every browser implemented such property in a slightly different way creating a [security and behavior mess across all browsers](https://gist.github.com/WebReflection/5370050) * due previous point, `Object.create(null)` may not be safe dictionaries since in some case adding a key `__proto__` will change the object inheritance instead of adding just the keyword proto * ES5 introduced `Object.getPrototypeOf` but not `Object.setPrototypeOf` which would ensure an explicit intent over the generic option instead of being a bomb keyword any object could potentially suffer for __Current Status__ Instead of formalizing its form, ES6 accepted `Object.setPrototypeOf` as described in specs and decided to silently move beside, but still have in specs, the dunder `__proto__` form, fixing at least a couple of related gotchas so that: * unless explicitly set as property, `__proto__` is a named property for every object that should not affect inheritance so that `obj[__proto__]` or `obj[key]` where `key` is the string `__proto__` should not hot/swap the prototypal chain * `obj.__proto__` is still valid when explicit, it should fail with `Object.create(null)` object but it should be a quick shortcut to create inheritance too such `var obj = {__proto__: null}` keeping compatibility but avoiding troubles with `JSON` serialized objects where once again `{__proto__:[]}` will behave as named property instead of prototype mutator. I hope these answers are OK and to all others, please correct me whenever you think whatever I've written is wrong. Best Regards, Andrea Giammarchi On Mon, Oct 14, 2013 at 12:51 PM, Benjamin (Inglor) Gruenbaum ing...@gmail.com wrote: Let me start by apologizing for adding noise to the list. I looked for discussion of the standardization of __proto__ in the ES6 spec and couldn't find any. This is probably my shortcoming but I didn't know where to look or how to search the mailing list. I found a lot of threads discussing possible problems with Object.create(null) and __proto__ but not the discussion and decision to include it in the spec and to tell browser vendors to implement it. And then Branden's famous reply where he says he thinks it's a horrible idea :) Frankly, when I heard a while back it was introduced it surprised me (why would objects suddenly change their prototype?) I'm really interested in hearing the arguments and counter-arguments for/against it. Thanks again and sorry. Benjamin Gruenabum. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Readdition of __proto__
On Mon, Oct 14, 2013 at 1:15 PM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: Yes, it's hard to search in this mailing list but luckily not everyone in here will tell you not to be that guy that clearly didn't read anything and is just annoying ^_^ Brendan, since you participated, above cit. wasn't at all directed to you! Anyway, yes, I still believe this ML is not as easy to lurk into as a forum would be plus TC39 meetings are huge and often dispersive. I hope my reply answered/summarized properly and quickly few major discussed points. Best Regards, Andrea Giammarchi ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Readdition of __proto__
Andrea Giammarchi wrote: __Current Status__ (Thanks for the dunders! :-P) Instead of formalizing its form, ES6 accepted `Object.setPrototypeOf` as described in specs and decided to silently move beside, but still have in specs, the dunder `__proto__` form, fixing at least a couple of related gotchas so that: * unless explicitly set as property, `__proto__` is a named property for every object that should not affect inheritance so that `obj[__proto__]` or `obj[key]` where `key` is the string `__proto__` should not hot/swap the prototypal chain I'm not sure what you mean here, but first, __proto__ is not specified in ES6 drafts as an own property. See http://people.mozilla.org/~jorendorff/es6-draft.html#sec-B.2.2.1 B.2.2.1 http://people.mozilla.org/%7Ejorendorff/es6-draft.html#sec-object.prototype.__proto__ Object.prototype.__proto__ Object.prototype.__proto__ is an accessor property with attributes { [[Enumerable]]: false, [[Configurable]]: true }. The [[Get]] and [[Set]] attributes are defined as follows B.2.2.1.1 http://people.mozilla.org/%7Ejorendorff/es6-draft.html#sec-get-object.prototype.__proto__ get Object.prototype.__proto__ The value of the [[Get]] attribute is a built-in function that requires no arguments. It performs the following steps: 1. Let /O/ be the result of calling ToObject http://people.mozilla.org/%7Ejorendorff/es6-draft.html#sec-toobject passing the *this* value as the argument. 2. ReturnIfAbrupt http://people.mozilla.org/%7Ejorendorff/es6-draft.html#sec-returnifabrupt(/O/). 3. Return the result of calling the [[GetPrototypeOf]] internal method of /O/. B.2.2.1.2 http://people.mozilla.org/%7Ejorendorff/es6-draft.html#sec-set-object.prototype.__proto__ set Object.prototype.__proto__ The value of the [[Set]] attribute is a built-in function that takes an argument proto. It performs the following steps: 1. Let /O/ be CheckObjectCoercible http://people.mozilla.org/%7Ejorendorff/es6-draft.html#sec-checkobjectcoercible(*this* value)/./ 2. ReturnIfAbrupt http://people.mozilla.org/%7Ejorendorff/es6-draft.html#sec-returnifabrupt(/O/). 3. If Type http://people.mozilla.org/%7Ejorendorff/es6-draft.html#sec-ecmascript-data-types-and-values(/proto/) is neither Object or Null, then return /proto/. 4. If Type http://people.mozilla.org/%7Ejorendorff/es6-draft.html#sec-ecmascript-data-types-and-values(/O)/ is not Object, then return /proto/. 5. Let /status/ be the result of calling the [[SetPrototypeOf]] internal method of /O/ with argument /proto/. 6. ReturnIfAbrupt http://people.mozilla.org/%7Ejorendorff/es6-draft.html#sec-returnifabrupt(/status/). 7. If /status/ is *false*, then throw a *TypeError* exception. 8. Return /proto/. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Readdition of __proto__
__Thanks__ ! This is really above and beyond what I could have asked for. I really wish there was an easy way to search the list like tags. I've been reading for a while but when I want to bring up, learn more about or discuss things - not being able to search really sucks. It makes me want to avoid things because I know how frustrating repetition can be. My opinion is probably a bit radical (not sure how many people here agree with it), feel free to skip it as it's probably more of a rant :P No, honestly - don't read it. It's repeating things that have probably been said here before but I couldn't find (well, other than Branden here https://mail.mozilla.org/pipermail/es-discuss/2010-April/010917.html ). * it's widely available across all mobile and modern desktop browsers So is `with` but that still doesn't work in strict mode. I don't see why having a feature people agree is bad (at least in the way it's currently used) makes adding it for a standard a good idea. You can standardize it and still not require browsers to implement it. If you choose to implement __proto__ then... . it's faster than `Array.prototype.slice.call(genericCollection)` I __hope__ this is not really an argument people are considering for adding __proto__ to the spec. An optimization for `Array.prototype.slice.call(genericCollection)` can be done instead on vendor level. * some library early adopted `__proto__` and few others followed making a _de facto used_ approach to easily hot/swap inehritance This is the most problematic argument here in my opinion. We have this beautiful prototypical inheritance system in JavaScript that lets us write clean and expressive code by not pretending we have some half working type system and instead embracing behavioral typing. It's really great and I really like it. This behavioral typing system entails that we act sensible about our types, inheritance can really work nicely and if I keep to the LSP and other common design principles I find that my code in JavaScript is a lot more expressive than similar OOP code in structurally typed languages. Being able to mutate __proto__ breaks this. It breaks it bad. Suddenly, my `Dog` stops being an `Animal` or my `Car` stops being a `Vehicle`. This makes no sense, why would we enable people to break behavioral typing like this? This is just like the `delete` operator. The object creation case and getPrototypeOf make a lot of sense but mutating __proto__ _after_ an object has been created sounds like a horrible broken approach that shoots behavioral typing in the foot. Especially when I'm __removing__ stuff from the prototype of an object. Sorry for the long rant if you've gotten this far. On Mon, Oct 14, 2013 at 11:15 PM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: Yes, it's hard to search in this mailing list but luckily not everyone in here will tell you not to be that guy that clearly didn't read anything and is just annoying ^_^ Since I've personally pushed to drop `__proto__` I might be the right person to give you pros and cons. Feel free to ask me more, if necessary (off-topic: the double underscore to talk about dunder proto is a hilarious must) __Pros__ * some library early adopted `__proto__` and few others followed making a _de facto used_ approach to easily hot/swap inehritance * it's widely available across all mobile and modern desktop browsers * it's faster than `Array.prototype.slice.call(genericCollection)` which is the unique place where Zepto library, probably the main reason dunder is still here, decided to swap `querySelectorAll` results ignoring incompatibility with IE Mobile at that time not so popular (then, one of the reason IE11 wanted to adopt it) __Cons__ * due lack of proper specs, every browser implemented such property in a slightly different way creating a [security and behavior mess across all browsers](https://gist.github.com/WebReflection/5370050) * due previous point, `Object.create(null)` may not be safe dictionaries since in some case adding a key `__proto__` will change the object inheritance instead of adding just the keyword proto * ES5 introduced `Object.getPrototypeOf` but not `Object.setPrototypeOf` which would ensure an explicit intent over the generic option instead of being a bomb keyword any object could potentially suffer for __Current Status__ Instead of formalizing its form, ES6 accepted `Object.setPrototypeOf` as described in specs and decided to silently move beside, but still have in specs, the dunder `__proto__` form, fixing at least a couple of related gotchas so that: * unless explicitly set as property, `__proto__` is a named property for every object that should not affect inheritance so that `obj[__proto__]` or `obj[key]` where `key` is the string `__proto__` should not hot/swap the prototypal chain * `obj.__proto__` is still valid when explicit, it should fail with `Object.create(null)` object but
Re: Readdition of __proto__
Andrea Giammarchi mailto:andrea.giammar...@gmail.com October 14, 2013 1:32 PM I meant that IIRC `obj[__proto__]` should not invoke that Annex B specified getter (@Benjamin, Annex B is where you'll find everything related indeed) but `obj.__proto__` will ... unless once again I've missed some update. What you just wrote is not true of __proto__ in SpiderMonkey or other engines I can test (V8, JSC). It also can't be true via ES6 Annex B, since obj[key] and obj.foo where key = 'foo' both lookup prototype properties and will find Object.prototype.foo. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Readdition of __proto__
You are breaking an opened door with me and I've indeed pushed to **not** have `__dunder__` specd but, for how much remote anger I still have against some decision some famous library and its main author made few months ago ... * web developers and specially library authors are usually more pragmatic than rational ... they solve problems. If something is widely adopted and works they won't bother much with philosophy, I am sure you know what I mean * performance is always a good argument. I agree that if everything is screwed and slow, using `__proto__` instead of `slice` or `push` over a new instance won't give you much (the whole story in Zepto is that the collection has Zepto methods inherited so is not just slice but yeah, it could have been done differently for sure) * JavaScript is better than just OOP, it uses prototype but also it's able to borrow methods from everything and everywhere (mixin). Hot swapping the proto might be an easy, simple, fast, shortcut to promote, downgrade, or change state in a state-machine system with a single operation. In JS you can composite deleting and adding new methods (aka: invokable properties) so if you ave a similar approach you might want to opt for `__dunder__` Once again, I've been fighting to not have it in for some similar reason and other security concerns plus it has been discussed infinite times and I believe everyone participated. The current status is the best option for everyone hoping whatever library decides to hot/swap inheritance will do it with its own known objects/instances instead of anything that goes through that library. In such/latter case, I would simply ignore that library as too greedy. Right now: * zepto and others will keep using `__proto__` going dirty * you can avoid all of this without problems * others will forget about this with new ES6 Class syntax Annex B is also an indicator that such feature is secondary so it's not something JS engines should absolutely have (these will in any case) Best Regards On Mon, Oct 14, 2013 at 1:33 PM, Benjamin (Inglor) Gruenbaum ing...@gmail.com wrote: __Thanks__ ! This is really above and beyond what I could have asked for. I really wish there was an easy way to search the list like tags. I've been reading for a while but when I want to bring up, learn more about or discuss things - not being able to search really sucks. It makes me want to avoid things because I know how frustrating repetition can be. My opinion is probably a bit radical (not sure how many people here agree with it), feel free to skip it as it's probably more of a rant :P No, honestly - don't read it. It's repeating things that have probably been said here before but I couldn't find (well, other than Branden here https://mail.mozilla.org/pipermail/es-discuss/2010-April/010917.html ). * it's widely available across all mobile and modern desktop browsers So is `with` but that still doesn't work in strict mode. I don't see why having a feature people agree is bad (at least in the way it's currently used) makes adding it for a standard a good idea. You can standardize it and still not require browsers to implement it. If you choose to implement __proto__ then... . it's faster than `Array.prototype.slice.call(genericCollection)` I __hope__ this is not really an argument people are considering for adding __proto__ to the spec. An optimization for `Array.prototype.slice.call(genericCollection)` can be done instead on vendor level. * some library early adopted `__proto__` and few others followed making a _de facto used_ approach to easily hot/swap inehritance This is the most problematic argument here in my opinion. We have this beautiful prototypical inheritance system in JavaScript that lets us write clean and expressive code by not pretending we have some half working type system and instead embracing behavioral typing. It's really great and I really like it. This behavioral typing system entails that we act sensible about our types, inheritance can really work nicely and if I keep to the LSP and other common design principles I find that my code in JavaScript is a lot more expressive than similar OOP code in structurally typed languages. Being able to mutate __proto__ breaks this. It breaks it bad. Suddenly, my `Dog` stops being an `Animal` or my `Car` stops being a `Vehicle`. This makes no sense, why would we enable people to break behavioral typing like this? This is just like the `delete` operator. The object creation case and getPrototypeOf make a lot of sense but mutating __proto__ _after_ an object has been created sounds like a horrible broken approach that shoots behavioral typing in the foot. Especially when I'm __removing__ stuff from the prototype of an object. Sorry for the long rant if you've gotten this far. On Mon, Oct 14, 2013 at 11:15 PM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: Yes, it's hard to search in this
Re: Readdition of __proto__
Then I might have confused what decided with `JSON` serialization where `__proto__` will be a property and not a setter, neither a getter once deserialized. Is this correct? Yeah, I remember that different accessors looked weird to me too ... thanks for clarification. Best Regards On Mon, Oct 14, 2013 at 1:43 PM, Brendan Eich bren...@mozilla.com wrote: Andrea Giammarchi mailto:andrea.giammarchi@**gmail.comandrea.giammar...@gmail.com October 14, 2013 1:32 PM I meant that IIRC `obj[__proto__]` should not invoke that Annex B specified getter (@Benjamin, Annex B is where you'll find everything related indeed) but `obj.__proto__` will ... unless once again I've missed some update. What you just wrote is not true of __proto__ in SpiderMonkey or other engines I can test (V8, JSC). It also can't be true via ES6 Annex B, since obj[key] and obj.foo where key = 'foo' both lookup prototype properties and will find Object.prototype.foo. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Readdition of __proto__
From: es-discuss [es-discuss-boun...@mozilla.org] on behalf of Brendan Eich [bren...@mozilla.com] Our duty as a standards body includes specifying de-facto standards which browsers must implement to interop. __proto__ is one such. It's worth highlighting this aspect of the situation. This duty of standards bodies has, at least from what I can see from my limited vantage point, only recently become apparent. But it's a crucial part of being a standards body today. Relevant reading, from the dawn of time when this was becoming apparent in the HTML/web applications space (2004): http://ln.hixie.ch/?count=1start=1085764602 (I look forward to people with more experience than me coming by to tell me about how this is not as new-fangled a paradigm as I think it is :) ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Readdition of __proto__
`JSON` serialization = `JSON` parse On Mon, Oct 14, 2013 at 1:53 PM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: Then I might have confused what decided with `JSON` serialization where `__proto__` will be a property and not a setter, neither a getter once deserialized. Is this correct? Yeah, I remember that different accessors looked weird to me too ... thanks for clarification. Best Regards On Mon, Oct 14, 2013 at 1:43 PM, Brendan Eich bren...@mozilla.com wrote: Andrea Giammarchi mailto:andrea.giammarchi@**gmail.comandrea.giammar...@gmail.com October 14, 2013 1:32 PM I meant that IIRC `obj[__proto__]` should not invoke that Annex B specified getter (@Benjamin, Annex B is where you'll find everything related indeed) but `obj.__proto__` will ... unless once again I've missed some update. What you just wrote is not true of __proto__ in SpiderMonkey or other engines I can test (V8, JSC). It also can't be true via ES6 Annex B, since obj[key] and obj.foo where key = 'foo' both lookup prototype properties and will find Object.prototype.foo. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Readdition of __proto__
From https://docs.google.com/a/google.com/file/d/0BxVCLS4f8Sg5NWZmM2NjZWEtYmExMS00Y2EzLWE3ZTMtNzFmYjYwYzBiOTIw/edit?hl=en_US, apparently in 1988: The Committee’s overall goal was to develop a clear, consistent, and unambiguous Standard for the C programming language which codifies the common, existing definition of C and which promotes the portability of user programs across C language environments. The X3J11 charter clearly mandates the Committee to codify common existing practice. The Committee has held fast to precedent wherever this was clear and unambiguous. On Mon, Oct 14, 2013 at 1:53 PM, Domenic Denicola dome...@domenicdenicola.com wrote: From: es-discuss [es-discuss-boun...@mozilla.org] on behalf of Brendan Eich [bren...@mozilla.com] Our duty as a standards body includes specifying de-facto standards which browsers must implement to interop. __proto__ is one such. It's worth highlighting this aspect of the situation. This duty of standards bodies has, at least from what I can see from my limited vantage point, only recently become apparent. But it's a crucial part of being a standards body today. Relevant reading, from the dawn of time when this was becoming apparent in the HTML/web applications space (2004): http://ln.hixie.ch/?count=1start=1085764602 (I look forward to people with more experience than me coming by to tell me about how this is not as new-fangled a paradigm as I think it is :) ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Readdition of __proto__
On Mon, Oct 14, 2013 at 4:47 PM, Brendan Eich bren...@mozilla.com wrote: Benjamin (Inglor) Gruenbaum mailto:ing...@gmail.com October 14, 2013 1:33 PM __Thanks__ ! This is really above and beyond what I could have asked for. Beware that what Andreas wrote about __proto__ in ES6 was not accurate. I really wish there was an easy way to search the list like tags. I've been reading for a while but when I want to bring up, learn more about or discuss things - not being able to search really sucks. It makes me want to avoid things because I know how frustrating repetition can be. There is also http://esdiscuss.org/ -- give it a try. Follow @esdiscuss (Domenic runs it) on twitter too! My opinion is probably a bit radical (not sure how many people here agree with it), feel free to skip it as it's probably more of a rant :P No, honestly - don't read it. It's repeating things that have probably been said here before but I couldn't find (well, other than Branden Brendan here https://mail.mozilla.org/**pipermail/es-discuss/2010-** April/010917.htmlhttps://mail.mozilla.org/pipermail/es-discuss/2010-April/010917.html). * it's widely available across all mobile and modern desktop browsers So is `with` but that still doesn't work in strict mode. Yes, but (or perhaps and in part, therefore) too few user strict mode. You are talking about apples to oranges. Excluding 'with' from ES5 strict leaves 'with' in the default-mode language. ES6 is not a new mode (1JS). We cannot make __proto__ go away by turning a blind eye toward it. Our duty as a standards body includes specifying de-facto standards which browsers must implement to interop. __proto__ is one such. Do you mean more then inclusion in Annex B? http://people.mozilla.org/~jorendorff/es6-draft.html#sec-other-additional-featuresThe committee and community made the right move to go with Object.setPrototypeOf(). Rick ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Readdition of __proto__
Rick Waldron wrote: Do you mean more then inclusion in Annex B? http://people.mozilla.org/~jorendorff/es6-draft.html#sec-other-additional-features http://people.mozilla.org/%7Ejorendorff/es6-draft.html#sec-other-additional-features The committee and community made the right move to go with Object.setPrototypeOf(). Indeed, we reached a happy place with Object.setPrototypeOf in the normative spec, and Annex B specifying __proto__ for those JS embeddings that need it for interop. I'm not sure why you think I'm dissenting from any of that. My reply was to correct a misstatement about __proto__, and only that. Context! /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Readdition of __proto__
I think you may have mixed up a few things: 1. JSON does not recognize '__proto__' per its unchanging spec, and so parsing that identifier makes an own data property. 2. var obj = {__proto__: proto}; is a special form, unlike any other identifier __proto__ as the literal property name does assign (set) not a define. 3. Annex B.2.2.1 defines an accessor on Object.prototype, which if unshadowed will be got or set when used by name on objects that actually delegate to Object.prototype. It's also delete-able (configurable), important for SES and the like. /be Andrea Giammarchi mailto:andrea.giammar...@gmail.com October 14, 2013 1:53 PM `JSON` serialization = `JSON` parse Andrea Giammarchi mailto:andrea.giammar...@gmail.com October 14, 2013 1:53 PM Then I might have confused what decided with `JSON` serialization where `__proto__` will be a property and not a setter, neither a getter once deserialized. Is this correct? Yeah, I remember that different accessors looked weird to me too ... thanks for clarification. Best Regards Brendan Eich mailto:bren...@mozilla.com October 14, 2013 1:43 PM What you just wrote is not true of __proto__ in SpiderMonkey or other engines I can test (V8, JSC). It also can't be true via ES6 Annex B, since obj[key] and obj.foo where key = 'foo' both lookup prototype properties and will find Object.prototype.foo. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss Andrea Giammarchi mailto:andrea.giammar...@gmail.com October 14, 2013 1:32 PM I meant that IIRC `obj[__proto__]` should not invoke that Annex B specified getter (@Benjamin, Annex B is where you'll find everything related indeed) but `obj.__proto__` will ... unless once again I've missed some update. Yeah, I know that you link stuff, and glad you made some time for extra clarification. Cheers Brendan Eich mailto:bren...@mozilla.com October 14, 2013 1:22 PM Andrea Giammarchi wrote: __Current Status__ (Thanks for the dunders! :-P) Instead of formalizing its form, ES6 accepted `Object.setPrototypeOf` as described in specs and decided to silently move beside, but still have in specs, the dunder `__proto__` form, fixing at least a couple of related gotchas so that: * unless explicitly set as property, `__proto__` is a named property for every object that should not affect inheritance so that `obj[__proto__]` or `obj[key]` where `key` is the string `__proto__` should not hot/swap the prototypal chain I'm not sure what you mean here, but first, __proto__ is not specified in ES6 drafts as an own property. See http://people.mozilla.org/~jorendorff/es6-draft.html#sec-B.2.2.1 B.2.2.1 http://people.mozilla.org/%7Ejorendorff/es6-draft.html#sec-object.prototype.__proto__ Object.prototype.__proto__ Object.prototype.__proto__ is an accessor property with attributes { [[Enumerable]]: false, [[Configurable]]: true }. The [[Get]] and [[Set]] attributes are defined as follows B.2.2.1.1 http://people.mozilla.org/%7Ejorendorff/es6-draft.html#sec-get-object.prototype.__proto__ get Object.prototype.__proto__ The value of the [[Get]] attribute is a built-in function that requires no arguments. It performs the following steps: 1. Let /O/ be the result of calling ToObject http://people.mozilla.org/%7Ejorendorff/es6-draft.html#sec-toobject passing the *this* value as the argument. 2. ReturnIfAbrupt http://people.mozilla.org/%7Ejorendorff/es6-draft.html#sec-returnifabrupt(/O/). 3. Return the result of calling the [[GetPrototypeOf]] internal method of /O/. B.2.2.1.2 http://people.mozilla.org/%7Ejorendorff/es6-draft.html#sec-set-object.prototype.__proto__ set Object.prototype.__proto__ The value of the [[Set]] attribute is a built-in function that takes an argument proto. It performs the following steps: 1. Let /O/ be CheckObjectCoercible http://people.mozilla.org/%7Ejorendorff/es6-draft.html#sec-checkobjectcoercible(*this* value)/./ 2. ReturnIfAbrupt http://people.mozilla.org/%7Ejorendorff/es6-draft.html#sec-returnifabrupt(/O/). 3. If Type http://people.mozilla.org/%7Ejorendorff/es6-draft.html#sec-ecmascript-data-types-and-values(/proto/) is neither Object or Null, then return /proto/. 4. If Type http://people.mozilla.org/%7Ejorendorff/es6-draft.html#sec-ecmascript-data-types-and-values(/O)/ is not Object, then return /proto/. 5. Let /status/ be the result of calling the [[SetPrototypeOf]] internal method of /O/ with argument /proto/. 6. ReturnIfAbrupt http://people.mozilla.org/%7Ejorendorff/es6-draft.html#sec-returnifabrupt(/status/). 7. If /status/ is *false*, then throw a *TypeError* exception. 8. Return /proto/. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Readdition of __proto__
On Mon, Oct 14, 2013 at 5:22 PM, Brendan Eich bren...@mozilla.com wrote: Rick Waldron wrote: Do you mean more then inclusion in Annex B? http://people.mozilla.org/~** jorendorff/es6-draft.html#sec-**other-additional-featureshttp://people.mozilla.org/~jorendorff/es6-draft.html#sec-other-additional-features http://people.mozilla.org/%**7Ejorendorff/es6-draft.html#** sec-other-additional-featureshttp://people.mozilla.org/%7Ejorendorff/es6-draft.html#sec-other-additional-features The committee and community made the right move to go with Object.setPrototypeOf(). Indeed, we reached a happy place with Object.setPrototypeOf in the normative spec, and Annex B specifying __proto__ for those JS embeddings that need it for interop. I'm not sure why you think I'm dissenting from any of that. I read through the entire thread and the message I was responding to read as though you meant that the committee would push forward on __proto__ (normative, non-annex) for the greater good of browser interop. It appears I may have read too much into your statement and I apologize for the confusion my response created. Rick ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Readdition of __proto__
Allen my confusion is with o4 ... what happens once you re-set/assign its `__proto__` there? Is it just a normal property so new value will be set ? Is it a magic inherited thing (it shouldn't) that will change the o4 prototype chain ? On Mon, Oct 14, 2013 at 5:32 PM, Allen Wirfs-Brock al...@wirfs-brock.comwrote: On Oct 14, 2013, at 4:21 PM, Andrea Giammarchi wrote: my last memories on the topic are these: ```javascript var obj = JSON.parse('{__proto__:[]}'); obj instanceof Array; // false obj.__proto__ instanceof Array; // true // since the proto is a property, not a magic thing obj.__proto__ = 123; // da hell will happen, only Allen knows ^_^ ``` And since latter should simply set the property named `__proto__` as value `123` I got confused with this dual way to deal with an object when it comes from JSON world (then has a property defined as value, not the inherited set/get from Object.prototype) As summary, `JSON.parse` over `__proto__` is similar to: ```javascript var o = {}; Object.defineProperty(o, '__proto__', { value: 123, enumerable: true, writable: true, configurable: true }); ``` Which means in such case the property `__proto__` will fail with such object while `Object.setPrototypeOf` won't which is the reason I keep suggesting the latest to make the intent explicit. Not arguing or anything, just speaking out loudly my confusion with that property as string part. I think you are over thinking this: Assuming that Annex B.2.2.1 and B.3.1 are implemented: here are the cases of interest: let o1 = {__proto__: p}; // o1 inherits from p let o2 = {__proto__: p}; // o2 inherits from p let o3 = {[__proto__]: p};// o3 inherits from Object.prototype, has own data property __proto__ whose value is p. let o4 = JSON.parse('{__proto__: value}'); //o4 inherits from Object.prototype, has own data property __proto__ whose value is value //assuming that Object.prototype.__proto__ has not been tamper with: let o5 = new Object; o5.__proto__ = p ; //o5 inherits from p let o6 =new Object; o6[__proto__] = p; //o6 inherits from p Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Readdition of __proto__
On Oct 14, 2013, at 5:54 PM, Andrea Giammarchi wrote: Allen my confusion is with o4 ... what happens once you re-set/assign its `__proto__` there? Is it just a normal property so new value will be set ? Is it a magic inherited thing (it shouldn't) that will change the o4 prototype chain ? JSON.parse is just a function that builds up simple (inheriting from Object.prototype) objects using [[DefineOwnProperty]] See http://people.mozilla.org/~jorendorff/es6-draft.html#sec-24.3.2 step 3.a.iv.3.a. So if the JSON object text contains a __proto__ property key, the object that is created with have a __proto__ own data property. If it doesn't then the Annex B2.2.1 Object.prototype__proto__ property is inherited. No magic involved. Allen ... Assuming that Annex B.2.2.1 and B.3.1 are implemented: here are the cases of interest: let o1 = {__proto__: p}; // o1 inherits from p let o2 = {__proto__: p}; // o2 inherits from p let o3 = {[__proto__]: p};// o3 inherits from Object.prototype, has own data property __proto__ whose value is p. let o4 = JSON.parse('{__proto__: value}'); //o4 inherits from Object.prototype, has own data property __proto__ whose value is value //assuming that Object.prototype.__proto__ has not been tamper with: let o5 = new Object; o5.__proto__ = p ; //o5 inherits from p let o6 =new Object; o6[__proto__] = p; //o6 inherits from p Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Readdition of __proto__
we are lucky enough there's no browser without a native JSON object that uses the D. Crockford polyfill ^_^ On Mon, Oct 14, 2013 at 6:20 PM, Allen Wirfs-Brock al...@wirfs-brock.comwrote: On Oct 14, 2013, at 5:54 PM, Andrea Giammarchi wrote: Allen my confusion is with o4 ... what happens once you re-set/assign its `__proto__` there? Is it just a normal property so new value will be set ? Is it a magic inherited thing (it shouldn't) that will change the o4 prototype chain ? JSON.parse is just a function that builds up simple (inheriting from Object.prototype) objects using [[DefineOwnProperty]] See http://people.mozilla.org/~jorendorff/es6-draft.html#sec-24.3.2 step 3.a.iv.3.a. So if the JSON object text contains a __proto__ property key, the object that is created with have a __proto__ own data property. If it doesn't then the Annex B2.2.1 Object.prototype__proto__ property is inherited. No magic involved. Allen ... Assuming that Annex B.2.2.1 and B.3.1 are implemented: here are the cases of interest: let o1 = {__proto__: p}; // o1 inherits from p let o2 = {__proto__: p}; // o2 inherits from p let o3 = {[__proto__]: p};// o3 inherits from Object.prototype, has own data property __proto__ whose value is p. let o4 = JSON.parse('{__proto__: value}'); //o4 inherits from Object.prototype, has own data property __proto__ whose value is value //assuming that Object.prototype.__proto__ has not been tamper with: let o5 = new Object; o5.__proto__ = p ; //o5 inherits from p let o6 =new Object; o6[__proto__] = p; //o6 inherits from p Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Readdition of __proto__
(early sent) I meant passing through the prototype. The unmagic behavior is when you deal with such object thinking accessing its `__proto__` will behave like others. So it's the other way round but again, I know all of this, I was just confused by it and explained indeed with an example code how it is simulating the `Object.defineProperty` Thanks anyway for clarifications. On Mon, Oct 14, 2013 at 6:43 PM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: we are lucky enough there's no browser without a native JSON object that uses the D. Crockford polyfill ^_^ On Mon, Oct 14, 2013 at 6:20 PM, Allen Wirfs-Brock al...@wirfs-brock.comwrote: On Oct 14, 2013, at 5:54 PM, Andrea Giammarchi wrote: Allen my confusion is with o4 ... what happens once you re-set/assign its `__proto__` there? Is it just a normal property so new value will be set ? Is it a magic inherited thing (it shouldn't) that will change the o4 prototype chain ? JSON.parse is just a function that builds up simple (inheriting from Object.prototype) objects using [[DefineOwnProperty]] See http://people.mozilla.org/~jorendorff/es6-draft.html#sec-24.3.2 step 3.a.iv.3.a. So if the JSON object text contains a __proto__ property key, the object that is created with have a __proto__ own data property. If it doesn't then the Annex B2.2.1 Object.prototype__proto__ property is inherited. No magic involved. Allen ... Assuming that Annex B.2.2.1 and B.3.1 are implemented: here are the cases of interest: let o1 = {__proto__: p}; // o1 inherits from p let o2 = {__proto__: p}; // o2 inherits from p let o3 = {[__proto__]: p};// o3 inherits from Object.prototype, has own data property __proto__ whose value is p. let o4 = JSON.parse('{__proto__: value}'); //o4 inherits from Object.prototype, has own data property __proto__ whose value is value //assuming that Object.prototype.__proto__ has not been tamper with: let o5 = new Object; o5.__proto__ = p ; //o5 inherits from p let o6 =new Object; o6[__proto__] = p; //o6 inherits from p Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss