みかづきブログ その3

3ヶ月つづけてみました。

falsyな値を確認しよう。

真偽値への変換

例えば、JavaScriptのif文の条件の中では真偽値以外の値も真偽値として評価することができます。

if (true) {
    alert("真"); // 実行されます
}

if (false) {
    alert("真"); // 実行されません
}

if (0) {
    alert("真"); // 実行されません
}

if (1) {
    alert("真"); // 実行されます
}

if ("( ' jjj ' )") {
    alert("真"); // 実行されます
}


これは、条件に使用された値をひっそりとBooleanオブジェクトに変換してくれているからとのことです。
真偽値が期待されているだろうところでは、真偽値のように振る舞える準備をしてくれるJavaScriptの空気読み力は、個人的には見習うべきところが満載だとすら思っています。
TPOってやつですね。

さてさて、条件に真偽値以外の値を渡した場合、舞台裏ではなにが起こなわれているのでしょうか。
今回は密着取材を敢行したいと思います。

舞台裏で行われていること

例えば、

"( ' jjj ' )"

という文字列を真偽値として評価しようとした場合は、

(new Boolean("( ' jjj ' )")).valueOf() // => true

もしくは、

Boolenan("( ' jjj ' )") // => true

という処理を行って真偽値に変換しているようです。
結構調べたんですが、どちらの処理を行っているのかはわかりませんでした。
ただ、この両者は同じ値を返します。

(new Boolean("( ' jjj ' )")).valueOf() === Boolenan("( ' jjj ' )") // => true

ちなみに、

!!"( ' jjj ' )" // => true

という記述でも真偽値に変換することもできます。余談です。

真偽値として評価した際にfalseになる値

さてさて、ではJavaScriptで真偽値として評価した際にtrueになる値、falseになる値はどのように決まっているのでしょうか。
一言で言ってしまえば、falseにならない値がtrueになります。
そして、falseっぽい値はfalseになります。そう。それがfalsyな値です。

falsyな値

false
0
NaN
""
undefined
null

いかにもfalseっぽい値ですね。

これらは真偽値に変換するとfalseになります。

Boolean(false)     // => false
Boolean(0)         // => false
Boolean(NaN)       // => false
Boolean("")        // => false
Boolean(undefined) // => false
Boolean(null)      // => false

真偽値として評価した際にtrueになる値


falseになる値以外はtrueになります。
例えば、0以外の数字、空以外の文字列、オブジェクト、配列はtrueになります。

Boolean(1)              // => true
Boolean(-1)             // => true
Boolean(8823)           // => true
Boolean(3.14)           // => true
Boolean(" ")            // => true
Boolean("false")        // => true
Boolean({})             // => true
Boolean({value: false}) // => true
Boolean([])             // => true
Boolean([false])        // => true

ここでよく誤解を生むのが、

new Boolean(false)

でつくったオブジェクトです。

typeof new Boolean(false); // => object

オブジェクトは中身に関係なくtrueと評価されるので、真偽値として評価した際にtrueになってしまいます。

Boolean(new Boolean(false)) // => true

なので例えば、

var hoge = new Boolean(false);

if (hoge) {
    alert(hoge); // => 実行される
}

と書くとif文の中に書いた処理が実行されてしまいます。

f:id:kimizuka:20140103145324p:plain

valueofメソッドを実行してプリミティブな値を取り出せばfalseとして評価されるようになります。

var hoge = new Boolean(false);

if (hoge.valueof()) {
    alert(hoge); // => 実行される
}


new演算子ではなくコンストラクタだけ実行すれば、プリミティブな真偽値が返ってくるので、

Boolean(false) // => false
typeof Boolean(false) // => boolean
Boolean(Boolean(false)) // => false

明示的に真偽値として評価したい場合は、

Boolean(hoge)

か、

!!hoge

をつかうのが直感的で良いとのことでした。
こちらからは以上です。