論理積(&&)と論理和(||)の短絡評価

if文で&&を使った際の挙動で思っていたのと違うということがあったので、調べたことをメモ。

サンプルコード

まずはif文で試す前に、オブジェクト内の値を取得するサンプルです。

const data = {
  name: 'suzuki',
  age: 18
};

console.log(data.size); // undefined
console.log(data.size.height); // Uncaught TypeError: Cannot read properties of undefined (reading 'height')

6行目のように存在しないkey値を取得しようとするとundefinedになり、7行目のようにundefinedに対して参照するとエラーになります。
undefinedの参照でエラーになるデモページ

上記でエラーになった参照をif文で使うと、同じくエラーになります。

const data = {
  name: 'suzuki',
  age: 18
};

if(data.size.height) { // Uncaught TypeError: Cannot read properties of undefined (reading 'height')
  console.log('if');
} else {
  console.log('else');
}

if文でエラーになるデモページ

次の例が本題ですが、if文で&&を使って以下のようにした場合も同様にエラーになるかと思っていたのですが、この場合はエラーにならずelseの方の分岐に入ります。

const data = {
  name: 'suzuki',
  age: 18
};

if(data.size && data.size.height) {
  console.log('if');
} else {
  console.log('else'); // else
}

if文でエラーにならないデモページ

「expr1 && expr2」で「expr1がtrue」かつ「expr2がtrue」の場合という条件になるになるという認識でいたのですが、以下に記載の通り、最初のexpr1がfalseだった時点でfalseを返す(以降の条件は確認しない)という処理になっているようです。

短絡評価

論理積の式は短絡演算子です。
各オペランドが論理値に変換されるとき、ある変換結果が false であった場合、論理積演算子は停止してその偽値のオペランドの元の値を返します。残りのオペランドは評価されません

以下の擬似コードを考えてみてください。

(偽値の式) && expr

expr の部分は評価されません。最初のオペランドである (偽値の式) が偽値と評価されるからです。
expr が関数であった場合、その関数は呼び出されません。

引用 – 論理積 (&&) – JavaScript | MDN

|| の場合も試してみます。

const data = {
  name: 'suzuki',
  age: 18
};

if(data.size || data.size.height) { // Uncaught TypeError: Cannot read properties of undefined (reading 'height')
  console.log('if');
} else {
  console.log('else');
}

&& を || に変更しましたが、この場合はエラーになります。
if文でエラーになるデモページ2

次に最初の条件がtrueになる例で試してみます。

const data = {
  name: 'suzuki',
  age: 18
};

if(data.name || data.size.height) {
  console.log('if'); // if
} else {
  console.log('else');
}

この場合はエラーになりませんでした。
if文でエラーにならないデモページ2

|| の場合、「expr1 || expr2」で「expr1がtrue」または「expr2がtrue」の場合という条件になりますが、この時 最初のexpr1がtrueの時点でtrueを返す(以降の条件は確認しない)という処理になっているようです。

短絡評価

論理和の式は左から右へと評価され、下記の規則を使用して「短絡」評価が可能なように評価されます。

(真値の式) || expr は短絡評価で真値の式に評価されます。

短絡とは、上記の expr の部分が評価されず、したがって、これを行うことの副作用が効果を及ぼさないことを意味します(例えば、 expr が関数呼び出しであった場合、この場では呼び出されません)。これは、最初のオペランドが評価された時点で、すでに演算子の値が決定しているためです。例を示します。

引用 – 論理和 (||) – JavaScript | MDN

参考サイト

このエントリーをはてなブックマークに追加

関連記事

コメントを残す

メールアドレスが公開されることはありません。
* が付いている欄は必須項目です

CAPTCHA


コメントが承認されるまで時間がかかります。

2024年11月
 12
3456789
10111213141516
17181920212223
24252627282930