Why ES6 introduced classes yet `Symbol` not to be used with `new`?

Claude Pache claude.pache at gmail.com
Mon Aug 15 06:33:27 UTC 2016


> Le 15 août 2016 à 07:33, Kris Siegel <krissiegel at gmail.com> a écrit :
> 
> Interesting.
> 
> Because, to be consistent with Number/String/Boolean you would expect `new Symbol()` to create a  Symbol wrapper object.
> 
> Currently Symbol is the only primitive that can't be converted to a string through the use of the + operator, so why the consistency in one place and the lack thereof in another? I understand there isn't really a meaningful representation of Symbol() as a string but I didn't see any particular reason in my cursory look at the past notes for it to throw an exception so I've been curious.

In short, preventing *implicit* conversion to string is for avoiding silent bugs. Typically, in situation where you expect a string, such as:

```js
foo[somePrefix_' + s] = bar[s]
```

This is not an inconsistency at the language level: implicit conversion to string is done using `.toString()` or `.@@toPrimitve("string")`, which has never been guaranteed to succeed. Example:

```js
var o = Object.create(null)
o + "" // will throw a TypeError
```


> 
> But we anticipated that if `new Symbol` was allowed many devs (who lacked an understanding of the difference between primitive values and wrapper objects for primitive values) would code `new Symbol()` with the expectation that they were creating a Symbol value. This would be a silent bug so we disallowed `new Symbol()`.
> 
> Forgive me for the ignorance but what kind of bug would this introduce?

Examples:

```js
var s = new Symbol
typeof s // "object", not "symbol"

switch (typeof s) {
case "symbol": // will not match
}
```

and:

```js
var s = new Symbol
var o = { }
o[s] = 42 // the wrapper object is converted to a primitive, 
var s2 = Object.getOwnPropertySymbols(o)[0]
s2 == s // true
s2 === s // false
```


> Since Symbol() is already an oddball compared to all other built-in objects and primitives would it have been so bad to simply make `new Symbol()` equate to `Symbol()`? I'm not sure you'll get developers to understand the difference between primitives and wrapper objects (still haven't found one yet who understands this in my inner-circle of JS devs that I know at least).

That would introduce an irregularity in the language, for `new Foo` has always been allowed to return an object only, not a primitive. The fact there is some lack of understanding among developers is not an excuse for increasing the confusion with inconsistent semantics.

The alternative design would have been to specify symbols as true objects rather than primitives. I recall that that alternative has been considered and discussed during the conception of ES6. You have to dig through the archives in order to find why one design was chosen over the other. The only thing I recall is that it was not a trivial decision.

—Claude

> 
> 
> On Sun, Aug 14, 2016 at 9:18 PM, Domenic Denicola <d at domenic.me <mailto:d at domenic.me>> wrote:
> I believe, but am not sure, that we also decided we would follow that pattern for any future primitive types, since in general constructing wrapper objects is a bad idea. (I want to say that wrapper objects themselves are a bad idea, but I think the conclusion was more subtle than that... they are an important part of the semantics, it's just unfortunate that they're so easy to create.)
> 
> If some enterprising person wants to dig through the meeting notes, there might be some hints there...
> 
> > From: Allen Wirfs-Brock [mailto:allen at wirfs-brock.com <mailto:allen at wirfs-brock.com>]
> >
> > Because, to be consistent with Number/String/Boolean you would expect `new Symbol()` to create a  Symbol wrapper object.  But we anticipated that if `new Symbol` was allowed many devs (who lacked an understanding of the difference between primitive values and wrapper objects for primitive values) would code `new Symbol()` with the  expectation that they were creating a Symbol value. This would be a silent bug so we disallowed `new Symbol()`.
> 
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org <mailto:es-discuss at mozilla.org>
> https://mail.mozilla.org/listinfo/es-discuss <https://mail.mozilla.org/listinfo/es-discuss>
> 
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160815/497788f5/attachment-0001.html>


More information about the es-discuss mailing list