Any reason why __proto__ is not a well known symbol?
On Mon, Feb 15, 2016 at 8:34 PM, JD Isaacks <jd at jisaacks.com> wrote:
I know ES2015 formally made the
__proto__
property a way to access/set an object's internal[[Prototype]]
property.Is there any reason why this wasn't spec'd as a well known symbol such as
@@__proto__
. It just seems like it would line up well with other modifiers like@@iterator
,@@species
, etc.
It was specified before symbols existed, and all implementations do it as a string property. If we were reinventing it today it would either be a symbol or something in the MOP, but are hands are tied by legacy.
Being that it was not formally spec'd it shouldn't have broke backwards compatibility either.
Backwards compat has nothing to do with specs, and everything to do with existing implementations. Multiple implementations agreed on proto, so our choice was either to leave it unstandardized or spec what the browsers did.
On Mon, Feb 15, 2016 at 8:51 PM, Tab Atkins Jr. <jackalmage at gmail.com> wrote:
It was specified before symbols existed, and all implementations do it as a string property. If we were reinventing it today it would either be a symbol or something in the MOP, but are hands are tied by legacy.
Being that it was not formally spec'd it shouldn't have broke backwards compatibility either.
Backwards compat has nothing to do with specs, and everything to do with existing implementations. Multiple implementations agreed on proto, so our choice was either to leave it unstandardized or spec what the browsers did.
Is there a migration to make it a Symbol in ES7? (ignorant question?)
Is there a migration to make it a Symbol in ES7? (ignorant question?)
Object.getPrototypeOf and Object.setPrototypeOf are the "no-dunder" ways to do it.
Object.getPrototypeOf and Object.setPrototypeOf are the "no-dunder" ways
to do it.
Not if you are trying to set in an object literal.
On Mon, Feb 15, 2016 at 9:14 PM, Coroutines <coroutines at gmail.com> wrote:
On Mon, Feb 15, 2016 at 8:51 PM, Tab Atkins Jr. <jackalmage at gmail.com> wrote:
It was specified before symbols existed, and all implementations do it as a string property. If we were reinventing it today it would either be a symbol or something in the MOP, but are hands are tied by legacy.
Being that it was not formally spec'd it shouldn't have broke backwards compatibility either.
Backwards compat has nothing to do with specs, and everything to do with existing implementations. Multiple implementations agreed on proto, so our choice was either to leave it unstandardized or spec what the browsers did.
Is there a migration to make it a Symbol in ES7? (ignorant question?)
There's a lot of code in the wild that uses proto and depends on it. We can't remove it until/unless that changes (it won't, at least not in the near future), and while we have proto, there's no reason to have anything else.
Object.getPrototypeOf
and Object.setPrototypeOf
works everywhere,
including null objects, as long as extension hasn't been prevented (
Objet.freeze
, Object.seal
or Object.preventExtension
)
It's __proto__
accessor that indeed doesn't work as expected in null
object, where it's always stored as key.
var dict = Object.create(null);
dict.__proto__ = [];
Object.keys(dict); // ["__proto__"]
dict instanceof Array; // false
Object.setPrototypeOf(dict, []);
dict instanceof Array; // true
However, if you want the key "__proto__"
you can specify it at string at
runtime {"__proto__": "this way"}
or use Object.defineProperty(obj, "__proto__", {value: "any"})
On Tue, Feb 16, 2016 at 1:23 AM, Tab Atkins Jr. <jackalmage at gmail.com>
wrote:
On Mon, Feb 15, 2016 at 9:14 PM, Coroutines <coroutines at gmail.com> wrote:
On Mon, Feb 15, 2016 at 8:51 PM, Tab Atkins Jr. <jackalmage at gmail.com> wrote:
It was specified before symbols existed, and all implementations do it as a string property. If we were reinventing it today it would either be a symbol or something in the MOP, but are hands are tied by legacy.
Being that it was not formally spec'd it shouldn't have broke backwards compatibility either.
Backwards compat has nothing to do with specs, and everything to do with existing implementations. Multiple implementations agreed on proto, so our choice was either to leave it unstandardized or spec what the browsers did.
Is there a migration to make it a Symbol in ES7? (ignorant question?)
There's a lot of code in the wild that uses proto and depends on it. We can't remove it until/unless that changes (it won't, at least not in the near future), and while we have proto, there's no reason to have anything else.
Is it too late to remove support for dunder-proto strictly within
module contexts? This might introduce a bit of a refactor hazard when
pulling old code into modules, but it's only the static obj.__proto__
usage that has any effect so this can be handled pretty easily with linter
warnings. Or it could be contextually reserved and throw an early exception.
As much as Id love to see dunder-__proto__
burn away from any future
specification, there are at least two use cases I do like in terms of
simplification:
- to shortcut literals with enumerable, configurable, and writable own
properties that extend known objects (or null) such
{__proto__:null, key: 'value'}
. This cannot be compared with the tediousObject.create(null, {key: {enumerable: true, writable: true, configurable: true, value: 'value'}})
- to explain inheritance through the console or to people in general, using it only as virtual-read-only reference to the inheritance chain
While the first point will be simplified a lot thanks to
Object.getOwnPropertyDescriptors
so that the literal form can be still
used via Object.create(null, Object.getOwnPropertyDescriptors({key: 'value'}))
the second point is still interesting but, like I've mentioned,
usable as abstract concept too that doesn't need to be specd' as magic
behavior.
Just my 2 cents
Best
On Tue, Feb 16, 2016 at 8:00 AM, Dean Landolt <dean at deanlandolt.com> wrote:
Is it too late to remove support for dunder-proto strictly within module contexts? This might introduce a bit of a refactor hazard when pulling old code into modules, but it's only the static
obj.__proto__
usage that has any effect so this can be handled pretty easily with linter warnings. Or it could be contextually reserved and throw an early exception.
I dunno, it just seems odd to cement it forever in JS when you can even feature-test for it (vs using a Symbol). At some point I really just expect people to keep up with with things and not be a Python 2 lazy person :D I hope ES7 makes breaking changes all over the place :p
On 2/16/16 12:01 PM, Coroutines wrote:
I hope ES7 makes breaking changes all over the place
Do you also hope ES7 never ships in any web browsers?
Just checking, Boris
For the sake of consistency and compatibility, instead of the following example:
{__proto__:null, key: 'value'}
Let this key be represented by a Symbol.proto
or Symbol.toPrototype
.
This would work fine to avoid using Object.create getting descriptors or
along Object.assign.
unless TC39 want to represent other Symbols within the __
notation,
__proto__
should be left alone and die in the first moment it's possible.
On Feb 16, 2016, at 8:00 AM, Dean Landolt <dean at deanlandolt.com <mailto:dean at deanlandolt.com>> wrote:
s it too late to remove support for dunder-proto strictly within module contexts? This might introduce a bit of a refactor hazard when pulling old code into modules, but it's only the static
obj.__proto__
usage that has any effect so this can be handled pretty easily with linter warnings. Or it could be contextually reserved and throw an early exception.
dunder proto as built-in property of Object.prototype is mode/syntactic context independent. It can be restricted in that manner.
On the other hand, the meaning of dunder-proto within an object literal is specified [1] as a syntactic form. So, in theory, its use could be restricted to specific syntactic contexts such as strict mode or not in a Module. ES2015 did not apply any such restrictions and given that strict mode and dunder-proto has co-existed in browsers since ES5 it’s unlike the we could purge it from strict mode. Making it illegal in Modules might still be feasible. It would probably take some some strong advocation within TC39 to make it happen.
Allen
[1] tc39.github.io/ecma262/#sec-proto-property-names-in-object-initializers tc39.github.io/ecma262/#sec-__proto__-property-names-in-object-initializers
Andrea Giammarchi wrote:
As much as Id love to see dunder-
__proto__
burn away from any future specification,
Before doing that, we should burn it away from everyones code :-)
there are at least two use cases I do like in terms of simplification:
1. to shortcut literals with enumerable, configurable, and writable own properties that extend known objects (or null) such `{__proto__:null, key: 'value'}` . This cannot be compared with the tedious `Object.create(null, {key: {enumerable: true, writable: true, configurable: true, value: 'value'}})`
The much simpler solution to that would be Object.setPrototypeOf({key: 'value'}, null)
(which also returns the object). Admittedly, putting
the prototype in the end is a bit awkward, and __proto__
in a literal
probably simplifies creation optimisations.
The way to overcome this would be to promote the prototype <|
operator, which
I would love to see in ES8. Anyone up for making an up-to-date proposal?
2. to explain inheritance through the console or to people in general, using it only as virtual-read-only reference to the inheritance chain
I wholeheartedly recommend to use the term [[prototype]] (in italics
or color) for this, and call it out as what it is: an internal
property. Don't teach people that __proto__
is a magical property - it
is not (causing confusion); and they only will start or continue using
it in new code.
Even in code examples, or simple demonstrations, use console.log(x, Object.getPrototypeOf(x))
over console.log(x, x.__proto__)
.
, Bergi
PS: Ceterum censeo proto esse delendum :-)
You break an open door and I was the one proposing setPrototypeOf
and to
kill __proto__
long time ago but about this:
Don't teach people that
__proto__
is a magical property - it is not (causing confusion); and they only will start or continue using it in new code.
I'm afraid my recent book is the only one I know that avoided dunder-proto.
Most other articles/books about "modern JS" all use and/or describe
__proto__
So we need people to stop using it, and modules would be a great opportunity to at least warn the community, and we need to stop talking about it in modern published online and offline books.
Best
I know ES2015 formally made the
__proto__
property a way to access/set an object's internal[[Prototype]]
property.Is there any reason why this wasn't spec'd as a well known symbol such as
@@__proto__
. It just seems like it would line up well with other modifiers like@@iterator
,@@species
, etc.Being that it was not formally spec'd it shouldn't have broke backwards compatibility either.