Symbol() + ''
throws
TypeError: Cannot convert a Symbol value to a string
While a known workaround is to use String(Symbol())
.
This looks inconsistent with other primitives, including the ones that should almost never be coerced (undefined
and null
).
How exactly does String
differ from + ''
(except it works)? Do specs explicitly specify that String
should accept symbols? What were the motives to allow it in one way and disallow it in another?
How exactly does String differ from + '' (except it works)? Do specs explicitly specify that String should accept symbols?
They differ in the aspect that String()
has a case for a Symbol()
, whereas the +
operator (when used for concatenation) directly calls the ToString()
operation which throws a TypeError
exception for a Symbol()
.
From String()
spec:
If NewTarget is undefined and Type(value) is Symbol, return SymbolDescriptiveString(value).
From +
evaluation spec:
If Type(lprim) is String or Type(rprim) is String, then
- Let lstr be ToString(lprim).
- ReturnIfAbrupt(lstr).
- Let rstr be ToString(rprim).
- ReturnIfAbrupt(rstr).
- Return the String that is the result of concatenating lstr and rstr.
Note: the definitions for lprim
and rprim
come from 10 previous steps in the evaluation process, which involve getting primitive types and values of the sides of the expression. I didn't include them to keep this post shorter. I have linked each specification I have referenced below.
From the ToString()
output:
Symbol: Throw a TypeError exception.
As for your final question:
What were the motives to allow it in one way and disallow it in another?
That's something for the writers at ECMA International.