问题
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