Consistency? What consistency? Where we’re going we don’t need any stinking consistency! #wtfjs #fucklogic pic.twitter.com/hrgI73ZOq3
— Lea Verou (@LeaVerou) 2017年8月7日
TC39 didn't want implicit conversion (e.g., via + '') but did want to allow explicit. Neither is too harsh. Both is secret/giant bug farm.
— BrendanEich (@BrendanEich) 2017年8月7日
Symbol("foo").toString()
とすると文字列に変換されるけど Symbol("foo") + ""
とすると TypeError: Cannot convert a Symbol value to a string となる。ポイントは明示的(explicit)か暗黙的(implicit)かで、Symbolでは明示的にtoString()を使用する分には問題ないけれど、暗黙的に型変換が行われようとすると TypeErrorを返す仕様となっている。暗黙的でなければ良いので、Symbol("foo").toString() + ""
とすれば問題なく使える。
文字列への型変換(Type Conversion)については、http://www.ecma-international.org/ecma-262/6.0/#sec-tostring のあたりが仕様となる。Objectを文字列へ型変換する場合はtoString()があればそれが使われる。一方、SymbolではTypeErrorとなる(SymbolにもtoStringメソッドはあるのだけど)。数値への型変換でも同様にTypeErrorとなる。
Symbolの利用目的 (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol) を考えると、ユニークなはずの値を暗黙的な型変換によってユニークに扱われずに問題を起こす... みたいなことは容易に想像できるので、妥当な感じはある。
Every symbol value returned from Symbol() is unique. A symbol value may be used as an identifier for object properties; this is the data type's only purpose. Some further explanation about purpose and usage can be found in the glossary entry for Symbol.
とはいえ、(console.logに出すとか)何の気なしにSymbolと合わせて文字列作ろうとしてTypeErrorが出て混乱することもありそう。
なので「Symbolでは文字列と数値への暗黙的な型変換はされない」という点は覚えておいてもいいかもしれない。