JavaScriptで頭に!!をつけるとfalseになる値とNaNの挙動について

[`evernote` not found]
[`livedoor` not found]
[`yahoo` not found]

今年はやりたいことがあるので、少し更新頻度落とします(といっても、2週間以上も空けるつもりはなかった・・・)。

JavaScriptでは、頭に!をつけるとその値を否定したブーリアン値になります。例えば下記のような感じです。

そしてさらにその値に!を着けたら否定の否定なので、!をつけてtrueのものはfalse、falseになるものはtrueとなる。つまり、頭に!!をつけて得た値は、Booleanメソッドを使った場合と同じ結果になる。

で、本題ですが、JavaScriptで演算子を使わない値(プリミティブ値)で、頭に!!をつけてfalseになる値は、false,数値の0,空文字,null,undefined,NaNの6種類だけです。

これ以外の演算子を使わない値はすべてtrueになります。一見、falseになりそうな空オブジェクトや空配列、Infinityや文字列の”0″はtrueになります。

さて、ここで演算子を使わない値を限定しました。なぜなら、演算子を使うとキリがないからです。一応、例を少しあげると下記のような値(というより、演算子をつけてるので式といったほうがいいかもしれません)が頭に!!をつけるとfalseとなります。なお、今回はわざわざ頭に!!をつけていますが、比較演算子(>や<、二つ以上つづく=の演算子)を使った式の場合、!!を使わなくても結果はBoolean値になります。

さて、ここで「あれ?」となった人もいるかもしれません。自分も先日、「あれ? 何でだ?」と思って記述ミスがないか見なおしてみましたが、どこも間違ったところはありませんでした。どうやら、NaN同士を==や===で比較した場合、結果はfalseとなるようです。 参考:NaN – JavaScript | MDN

例えば下記のようなcheckNaNという関数を作った場合、引数にNaNをいれても”NaNじゃない”という結果になってしまいます。

NaNかどうか調べたいときは、isNaNメソッドを使ってNaNかどうかを調べるのがよさそうです。

ここで、trueやnullがNaNじゃないとなっているのは、true-0が1、null-0が0になるからです。今回はわざわざ値から0を引いて数値変換していますが、実はそんなことをしなくても同じ結果になります。

これじゃあ困るという場合は、同じ値を同値比較した場合にfalseになるのがNaNだけというのを利用して、下記のようにすると、引数がNaNの場合だけが”NaNです”となります。

非常にわかりづらいので、こういう手法を取るときはコメントを書いたほうがいいと思います。というより、できるだけ使わないようにするのがいいと思います。

ところで、NaNはなぜ同値比較するとfalseになるのか理由を考えると、例えば、『”aiueo”-0』と『”abcde”-0』の比較は等しくなってほしくないからじゃないかと思いました(実際のところどうしてか分かってません)。で、そこで、Infinity(無限大)はどうなんだと思いました。結論からいうと、Infinity同士の比較はtrueになります。なので下記の比較はすべてtrueとなります(Infinityになる値は右記を参考:【Javascript】0で割ると? at softelメモ)。

少し違和感があるかもしれませんが、こういうものだと思いましょう。

コメントを残す

メールアドレスが公開されることはありません。