问题
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?
回答1:
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.
String() ES6 Spec
+ operator runtime evaluation ES6 Spec
ToString() Output behavior ES6 Spec
来源:https://stackoverflow.com/questions/45354760/symbol-string-coercion