JavaScriptで「undefined + 1」を「NaN」ではなく「1」にする

JavaScriptでこういう式を書くとNaNになります。

var x = {};

x.key += 1; // NaN

perlなら1になるのになぁ〜

対処法として、このように書くことが多いのではないでしょうか?

var x = {};

x.key = isNaN(x.key) ? 1 : x.key + 1; // 1

x.keyがあるかどうかで見てるんですね。hasOwnProperty()を使うこともあるかも知れません。

実はこうも書けます。

var x = {};

x.key = Number([x.key]) + 1; // 1
x.key = Number([x.key]) + 1; // 2
x.key = Number([x.key]) + 1; // 3
x.key = Number([x.key]) + 1; // 4

こちらのほうが分岐もありませんし、簡単ではないでしょうか?


なぜでしょう?

でもなぜこういう挙動になるのでしょう?まず、単体でNumber()の挙動を確かめてみます。

Number(null); // 0

Number(undefined); // NaN
Number(""); // 0
Number(); // 0

また、未定義のメンバの値はどうなるのでしょう?

var x = {};

x.key // undefined

x.key が未定義なのでundefined + 1 → NaN + 1 → NaN となるわけですね。

ではなぜ [x.key] が 0になったのでしょう?

var x = {};

[x.key] // [undefined]

undfinedのままですね。

ここでNumber(値)の処理がポイントになります。

Numberの値が数字っぽく評価されるように変換されるんですね。

配列の場合は.join()が呼ばれるようです。

なので、Number([undefined]) → Number([undefined]. join()) → Number("") → 0 となるわけです。

複雑怪奇ですねw