最近よくJavaScriptを書いています.
if (a && b) { alert("test"); }
という処理があったとして,aがfalseだった場合にbは評価されるのか少し気になって調べていました.
そのときに && と || の動作について書かれているページを見たのですが,今ままで考えていた動作とは違う動作をしていることに衝撃を受けました.
(いやまぁ知らないほうが恥ずかしいのかもしれませんが…)
JavaやC系の経験で && と || の論理演算の結果はBoolean型で返ってくるものだと思っていました.
ですが,JavaScriptでは必ずしもBoolean型で返ってくるとは限らないのです.
JavaScriptの仕様となるECMAScriptには以下のように書いてあります.
The value produced by a && or || operator is not necessarily of type Boolean.
The value produced will always be the value of one of the two operand expressions.
訳すと
&&演算子または||演算子によって生成される値は必ずしもBoolean型である必要はありません。
生成される値は,常に2つのオペランド式のうちの1つの値になります.
という訳なのです.
これだけ見ても「?」な感じなので解説します.
まずは &&
value1 && value2
value1がfalseと判定できる場合,value1が返ってきます.
そうでない場合,value2が返ってきます.
片方がtrueもう片方がfalseの場合はfalseが返ってきます.
次は ||
value1 || value2
value1がtrueと判定できる場合,value1が返ってきます.
そうでない場合,value2が返ってきます.
片方がtureもう片方がfalseの場合はtrueが返ってきます.
衝撃です…!!
JavaScriptではFalseと判定されるものが多くあります.
false,Undefined,Null,0,空文字など…
ので,条件分岐(ifとか)と共に&& や ||を使うと,あたかもBoolean型で返ってきてしまうように錯覚していまいます.
実際はどちらかの値が返ってきて,条件分岐でBoolean型として再度判定されているのです.
JavaScript初心者なので知らなかったです.
3項演算子が好きで,値がないときは空文字,値があるときはその値を返すという処理をするとき
var value = value1 ? value1 : "";
こういうコードを書くのですが,value1が関数で処理が重いと2度呼ぶ手間があるし,変数にするのも手間があるし,うーんって思ってましたが,
var value = value1 || "";
と書けば解決するので,とても気持ちが良いです.
ちなみにこれ,Pythonでも同じ動作するようです…(Python3.6で確認済み)
いや~,いい勉強になりました.
(2017/2/27 追記)
ちなみに冒頭の評価の話ですが, && の話から,左辺が評価された段階で右辺は評価されずにif文の分岐に入ります.