Shocking statement
console.log([] + []); // ""
console.log([] + {}); // "[object Object]"
console.log({} + []); // 0
奇々怪々
[] + []
/*--- `[] + []` ---*/
/* `+`演算子の両辺がobject(配列を含む)である場合、これらをプリミティブ値に変換する */
/* 変換ではまず`valueOf()`が呼ばれるが返値は`[]`である */
/* プリミティブ値ではないため次に`toString()`が呼ばれる */
/* 配列の`toString()`は内部で`join(", ")`を実行する` */
/* `[].join(", ")`は当然`""`(空文字列)を返すので、 */
console.log("" + ""); // ""
[] + {}
/*--- `[] + {}` ---*/
/* `+`演算子の両辺がobject(配列を含む)である場合、これらをプリミティブ値に変換する */
/* `[]`の変換は上記の通り`""`になる */
// "" + {}
/* `{}`の変換ではまず`valueOf()`が呼ばれるが返値は`{}`である */
/* 次に`toString()`が呼ばれ、その返値は一般的なオブジェクトの場合その型を示すデフォルトの文字列である`[object Object]`となるので、 */
console.log("" + "[object Object]"); // "[object Object]"
{} + []
/*--- `{} + []` ---*/
/* (この結果は実行環境による) */
/* 最初に記述された`{}`はobjectではなく空のコードブロックと解釈される */
// `+ []`
/* 残った`+ []`は単項プラス演算子による数値変換が行われる */
/* 単項プラス演算子はまずオペランドをプリミティブ値に変換する */
/* `[].valueOf()`は`[]`、`[].toString()`は`""`となり、 */
// `+ ""`
/* 次に、単項プラス演算子は`""`を数値に変換する */
/* `""`は0に変換されるため、 */
console.log(+0); // 0
文字列から数値への変換処理
ToNumber
- 数字が含まれるならば、
"123" -> 123
- 空文字列ならば、
"" -> 0
- 解釈できないならば、
abc -> NaN
やはりひどい例
JavaScriptでは空配列と空配列の否定は等値である
おなじくひどい例
JavaScript baNaNa
ちなみに - php も大概である
/* 数値として比較している */
"123" == 123; // true
/* 数値として比較している */
"123" == "0123"; // true
/* 数値として比較できないなら問答無用で0にする */
"NoWayThisIsTrue" == 0; // true