JavaScriptには4つの論理演算子があります: ||
(OR:論理和), &&
(AND:論理積), !
(NOT:否定), ??
(Null合体)。ここでは最初の3つを説明し、??
演算子は次の記事で説明します。
これらは “論理” と呼ばれますが、Boolean 型だけでなく、どの型の値にも適用することができます。結果もまた任意の型になります。
では、詳細を見ていきましょう。
|| (OR)
“OR” 演算子は2つの縦の記号で表現されます:
result = a || b;
古典的なプログラミングでは、論理和は真偽値のみを操作することを意味していました。もしもその引数のいずれかが true
の場合、それは true
を返します。そうでなければ false
を返します。
JavaScriptでは、演算子は少し難解ですが強力です。最初に真偽値で起こることを見てみましょう。
4つの取りうる論理的な組み合わせがあります:
alert( true || true ); // true
alert( false || true ); // true
alert( true || false ); // true
alert( false || false ); // false
ご覧の通り、両方のオペランドが false
の場合を除き、結果は常に true
です。
もしもオペランドが Boolean でない場合、評価のために Boolean に変換されます。
例えば、数値 1
は true
として扱われ、数値 0
は false
となります:
if (1 || 0) { // if( true || false ) のように動作します
alert( 'truthy!' );
}
ほとんどの場合、OR ||
は if
文の中で、与えられた条件のいずれかが正しいかを確認するのに使われます。
例:
let hour = 9;
if (hour < 10 || hour > 18) {
alert( 'The office is closed.' );
}
より多くの条件を書くこともできます:
let hour = 12;
let isWeekend = true;
if (hour < 10 || hour > 18 || isWeekend) {
alert( 'The office is closed.' ); // 週末です
}
OR は最初の真値を探します
上で描かれたロジックはいくらか古典的です。ここで JavaScriptの特別な機能を持ってきましょう。
拡張されたアルゴリズムは次の通りに動作します。
与えられた複数の OR の値:
result = value1 || value2 || value3;
OR "||"
演算子は次のように動きます:
- 左から右にオペランドを評価します。
- それぞれのオペランドで、それを Boolean に変換します。もしも結果が
true
であれば、停止しオペランドの本来の値を返します。 - もしもすべての他のオペランドが評価された場合(i.e. すべて
偽
のとき), 最後のオペランドを返します。
値は変換されていない元の形式で返却されます。
つまり、OR "||"
のチェーンは最初に真となる値を返し、そのような値がない場合には最後のオペランドが返却されます。
例:
alert( 1 || 0 ); // 1 (1 は真)
alert( null || 1 ); // 1 (1 は最初の真値)
alert( null || 0 || 1 ); // 1 (最初の真値)
alert( undefined || null || 0 ); // 0 (すべて偽、なので最後の値が返却される)
この結果は、“純粋で昔ながらの真偽値のみの OR” と比較して、いくつかの興味深い使用方法につながります。
-
変数または式のリストから最初の真値を取得する
例えば、
firstName
,lastName
とnickName
変数があり、すべて任意( undefined あるいは偽となる値になりうる)とします。データを持っているものを選び、表示する(あるいは何も設定されていな場合は
"Anonymous"
)のに、OR||
が利用できます:let firstName = ""; let lastName = ""; let nickName = "SuperCoder"; alert( firstName || lastName || nickName || "Anonymous"); // SuperCoder
すべての変数が偽であれば、
"Anonymous"
が表示されます。 -
短絡評価(最小評価)
OR
||
のもう1つの特徴はいわゆる “短絡” 評価と呼ばれます。つまり、
||
は最初の真値に到達するまで引数を処理し、その後は他の引数には触れることなく、値はすぐに返却されることを意味します。この機能の重要性は、オペランドが単なる値ではなく、変数の割当や関数呼び出しなどの副作用のある式である場合に明らかになります。
以下の例を実行した場合、2つ目のメッセージだけが表示されます:
true || alert("not printed"); false || alert("printed");
1行目では、OR
||
演算子がtrue
を見るとすぐに評価を停止するため、alert
は実行されません。条件の左側が false のときにだけコマンドを実行するためにこの特徴を利用する人もいます。
&& (AND)
AND 演算子は2つのアンパサンド &&
で表されます:
result = a && b;
古典的なプログラミングでは、AND は両方のオペランドが真のときに true
を返します。それ以外の場合は false
です:
alert( true && true ); // true
alert( false && true ); // false
alert( true && false ); // false
alert( false && false ); // false
if
の例:
let hour = 12;
let minute = 30;
if (hour == 12 && minute == 30) {
alert( 'Time is 12:30' );
}
OR のように、AND のオペランドとして任意の値が許可されています:
if (1 && 0) { // true && false として評価される
alert( "won't work, because the result is falsy" );
}
AND は最初の偽値を探します
複数のANDされた値が与えられました:
result = value1 && value2 && value3;
AND "&&"
演算子は次のように動きます:
- 左から右にオペランドを評価します。
- それぞれのオペランドで、それを Boolean に変換します。もしも結果が
false
の場合、ストップしそのオペランドの本来の値を返します。 - もしもすべての他のオペランドが評価された場合(i.e. すべて
真
のとき), 最後のオペランドを返します。
つまり、ANDは最初の偽値、またはない場合には最後の値を返します。
上のルールはORと似ています。違いはANDは最初の 偽値 でORは最初の 真値 です。
例:
// 最初のオペランドが真の場合、
// AND は2つ目のオペランドを返す:
alert( 1 && 0 ); // 0
alert( 1 && 5 ); // 5
// 最初のオペランドが偽の場合、
// AND はそれを返します。2つ目のオペランドは無視されます。
alert( null && 5 ); // null
alert( 0 && "no matter what" ); // 0
より多くの値を渡すこともできます。どのように最初の偽値が返却されるか見てください。:
alert( 1 && 2 && null && 3 ); // null
すべての値が真のとき、最後の値が返却されます。:
alert( 1 && 2 && 3 ); // 3, 最後のオペランド
&&
は OR ||
の前に実行しますAND &&
演算子の優先順位は OR ||
よりも高いです。
そのため、コード a && b || c && d
は &&
式が括弧の中にある場合 (a && b) || (c && d)
と本質的に同じです。
if
を ||
や &&
に置き換えないでください時々、AND &&
演算子を “if
を短く書く方法” として利用する人がいます。
例:
let x = 1;
(x > 0) && alert( 'Greater than zero!' );
&&
の右側のアクションは、その評価に到達した場合にのみ実行されます。つまり: (x > 0)
が true の場合のみです。
なので、基本的に同じことをする別の方法があります:
let x = 1;
if (x > 0) alert( 'Greater than zero!' );
&&
を含むやり方は、より短いように見えますが、if
はより明白で、読みやすい傾向にあります。そのため、すべての構文をその目的に合わせて使うことを推奨します。条件判定が必要なら if
を、論理積が必要なら &&
を使います。
! (NOT)
真偽値否定演算子は感嘆符 "!"
で表現されます。
構文はとてもシンプルです:
result = !value;
演算子は1つの引数を取り、次のようにします:
- オペランドを真偽値型に変換します:
true/false
。 - 逆の値を返します。
例:
alert( !true ); // false
alert( !0 ); // true
2つの否定 !!
は値を真偽値型に変換するために使われることがあります:
alert( !!"non-empty string" ); // true
alert( !!null ); // false
つまり、最初の NOT は値を真偽値に変換しその逆を返します。そして、2つ目の NOT は再びその逆をします。最終的に、明示的な値からブール値への変換を行います。
少し冗長ですが同じことをする方法があります – 組み込みの Boolean
関数です。:
alert( Boolean("non-empty string") ); // true
alert( Boolean(null) ); // false
NOT !
の優先順はすべての論理演算子でもっとも高いので、&&
や ||
よりも常に最初に実行されます。