JavaScriptには3つの論理演算子があります: || (OR:論理和), && (AND:論理積), ! (NOT:否定)

それらは “論理” と呼ばれますが、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 に変換されます。

例えば、数値 1true として扱われ、数値 0false となります:

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( true || 'no matter what' ); // (true は真)

alert( null || 1 ); // 1 (1 は最初の真値)
alert( null || 0 || 1 ); // 1 (最初の真値)
alert( undefined || null || 0 ); // 0 (すべて偽、なので最後の値が返却される)

それは “純粋で昔ながらの真偽値のみの OR” と比較して、いくつかの興味深い使用方法につながります。

  1. 変数または式のリストから最初の真値を取得する

    変数がいくつかある状態を想像してください。そして、それらの変数は値を持つか null/undefined とします。そして、今、私たちは最初のデータ(null/undefined ではない値)を選ぶ必要があります。

    このために OR || が利用できます:

    let currentUser = null;
    let defaultUser = "John";
    
    let name = currentUser || defaultUser || "unnamed";
    
    alert( name ); // "John" – 最初の真値です

    currentUserdefaultUser が共に偽の場合、"unnamed" が結果になります。

  2. 短絡評価(最小評価)

    オペランドには値だけでなく、任意の式を使用できます。 ORは左から右へ評価、テストをします。 真値に到達したとき、評価はストップし、その値が返却されます。この処理は左から右にできるだけ短くなるように行われるため、“短絡評価” と呼ばれます。

    これは、2番目の引数として与えられた式が変数への代入のような、副作用を持つ場合によく分かります。:

    下の例を実行した場合、x は割り当てられません。:

    let x;
    
    true || (x = 1);
    
    alert(x); // undefined, なぜなら (x = 1) は評価されないからです

    …また、1つ目の引数が false の場合、 OR は次へ行き2つ目の評価を行い、代入をします:

    let x;
    
    false || (x = 1);
    
    alert(x); // 1

    代入は単純なケースであり、他の副作用が発生する可能性があります。

    ご覧のように、このようなユースケースは "if をするより短い方法" です。最初のオペランドは真偽値に変換され、もしもそれが偽の場合は2つ目が評価されます。

    便利なときもありますが、たいていの場合は理解しやすいコードにするために、 if を使う方がよいでしょう。

&& (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, 最後のオペランド
AND && は OR || の前に実行します

AND && 演算子の優先順位は OR || よりも高いです。そのため、ORの前に実行されます。

下のコードでは、1 && 0 が最初に計算されます:

alert( 5 || 1 && 0 ); // 5

ORのように、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 が必要なら if を使います。AND が必要なら && を使います。

! (NOT)

真偽値否定演算子は感嘆符 "!" で表現されます。

構文はとてもシンプルです:

result = !value;

演算子は1つの引数を取り、次のようにします:

  1. オペランドを真偽値型に変換します: true/false
  2. 逆の値を返します。

例:

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

タスク

重要性: 5

下のコードは何を出力するでしょう?

alert( null || 2 || undefined );

答えは 2 で、それが最初の真となる値です。

重要性: 3

下のコードは何を出力するでしょう?

alert( alert(1) || 2 || alert(3) );

答え: 最初は 1, 次に 2.

alert( alert(1) || 2 || alert(3) );

alert の呼び出しは値を返しません。また、言い換えると、 undefined を返します。

  1. 最初の OR || はその左のオペランド alert(1) を検査します。それは 1 の最初のメッセージを表示します。
  2. alertundefined を返すので、OR は真値を探すのに2つ目のオペランドに行きます。
  3. 2つ目のペランド 2 は真値なので、実行が中止され 2 が返却されます。次に外部の alert でそれが表示されます。

検査は alert(3) に到達しないので、 3 は現れません。

重要性: 5

このコードは何を表示するでしょう?

alert( 1 && null && 2 );

答え: null です。なぜなら、それがリストの中の最初の偽値だからです。

alert( 1 && null && 2 );
重要性: 3

下のコードは何を表示するでしょう?

alert( alert(1) && alert(2) );

答え: 1, 次に undefined

alert( alert(1) && alert(2) );

alert の呼び出しは undefined を返します(メッセージを表示するだけなので、意味のある返却はありません)。

そのため、 && が左のオペランドを検査(1 を出力)し、すぐに停止します。なぜなら、undefined は偽値だからです。そして && は偽値を探し、それを返します。

重要性: 5

結果はどうなるでしょう?

alert( null || 2 && 3 || 4 );

答え: 3.

alert( null || 2 && 3 || 4 );

AND && の優先順位は || よりも高いので、最初に実行されます。

2 && 3 = 3 なので、式はこのようになります:

null || 3 || 4

これの最初の真値の結果なので、3 です。

重要性: 3

包括的に age1490 の間かをチェックする if 条件を書きなさい。

“包括的に” は age14 または 90 の端に到達できることを意味します。

if (age >= 14 && age <= 90)
重要性: 3

包括的に age が 14 と 90 間ではないことをチェックするための if 条件を書きなさい。

2つのバリアントを作ってください: 最初は NOT ! を使い、2つ目は – それなしです。

最初のバリアント:

if (!(age >= 14 && age <= 90))

2つ目のバリアント:

if (age < 14 || age > 90)
重要性: 5

これらの alert で実行されるのはどれでしょう?

if(...) の内側の式の結果はどうなるでしょう?

if (-1 || 0) alert( 'first' );
if (-1 && 0) alert( 'second' );
if (null || -1 && 1) alert( 'third' );

答え: 1つ目と3つ目が実行されます。

詳細:

// 実行します
// -1 || 0 = -1 なので真です
if (-1 || 0) alert( 'first' );

// 実行されません
// -1 && 0 = 0, 偽です
if (-1 && 0) alert( 'second' );

// 実行します
// 演算子 && は || よりも高い優先順位を持っています
// なので -1 && 1 が最初に実行されます:
// null || -1 && 1  ->  null || 1  ->  1
if (null || -1 && 1) alert( 'third' );
チュートリアルマップ

コメント

コメントをする前に読んでください…
  • 自由に記事への追加や質問を投稿をしたり、それらに回答してください。
  • 数語のコードを挿入するには、<code> タグを使ってください。複数行の場合は <pre> を、10行を超える場合にはサンドボックスを使ってください(plnkr, JSBin, codepen…)。
  • 記事の中で理解できないことがあれば、詳しく説明してください。