JavaScriptの論理演算子について、分かっているようで分からなかったのでメモ。
論理演算子とは
そもそも論理演算子とはなんぞや?ですが、主にif文で使います。
下記のように「&&」「||」「!」を使って条件を判定します。
// True判定されると、コンソールが表示されます
// 論理和(||)
if(1 || null) { // 左辺または右辺がTrueの場合はTrue判定される
console.log("条件に合致しました"); //出力される
}
// 論理積(&&)
if(1 && null) { // 左辺と右辺がTrueの場合はTrue判定される
console.log("条件に合致しました"); //出力されない
}
// 論理否定(!)
if(!(1 && null)) { // Trueの場合False、Falseの場合はTrue判定される
console.log("条件に合致しました"); //出力される
}
条件式のif文で、どれか1つでも条件に一致していれば実行、全て一致していなければ実行しない。といった使い方をします。
Null 合体演算子とは
Null 合体演算子とは、左辺がnull または undefinedの場合だけ右辺を出力し、それ以外は左辺が出力されます。if文だと次のような使い方ができます。
// Null 合体演算子(??)
if(null ?? 1) { //
console.log("条件に合致しました"); //出力される
}
Null 合体演算子は、変数に演算子の結果を格納する時、使用することが多いです。
const result = null ?? "値はnull、またはundefinedです。";
// 変数「result」に"値はnull、またはundefinedです。"が格納される。
const result = "値はnull、undefined以外です。" ?? "値はnull、またはundefinedです。";
// 変数「result」に"値はnull、undefined以外です。"が格納される。
記号の一覧
記号の意味は次の通りです。
論理積 | && | 判定全てがTrueの場合、Trueを返す |
論理和 | || | 判定の1つでもTrueの場合、Trueを返す |
論理否定 | ! | 実際の判定の逆を返す。 判定がTrueの場合は、False を返し、Falseの場合は、True を返す。 |
Null 合体演算子 | ?? | 左辺がnull または undefinedの場合だけ、右辺を出力、それ以外は左辺が出力される True、False判定は出力結果に左右される |
True、Falseになる値にはどんなものがあるか
先ほどの条件式では、数字の1がTrue判定されています。
何もないことを表すnullなら何となく分かりますが、数字の1がどうしてTrue判定されるのか、、?
調べたところ、Falseになるのは主に次の値です。これ以外はTrueになると思います。
Falseになる値
- 0(数字)
- NaN
- 空文字
- null
- undefind
実際の判定結果をconsole.logに出力しました。判定結果をTrue、Falseで表示させるために(!!)で判定結果を逆の逆にしています。なお、数字の0を厳密に判定するには、Number()メソッドで数値に変換してあげた方が良いらしいです。
console.log("0の判定結果:" + !!(Number(0)));
console.log("NaNの判定結果:" + !!(NaN));
console.log("空文字の判定結果:" + !!(""));
console.log("nullの判定結果:" + !!(null));
console.log("undefinedの判定結果:" + !!(undefined));
See the Pen resultConditionFalse by donguri2020 (@m-ke) on CodePen.
Trueになる値
Falseになる値以外がTrueになりますが、勘違いしそうなものをまとめました。
- 数字の0以上
- 空の配列
- 空のオブジェクト
- 空でない文字列
こちらの判定結果を確認してみます。
console.log("1の判定結果:" + !!(1));
console.log("空配列の判定結果:" + !!([]));
console.log("空のオブジェクトの判定結果:" + !!({}));
console.log("空でない文字列の判定結果:" + !!("あいうえお"));
実際の判定結果は次のようになります。
See the Pen resultConditionTrue by donguri2020 (@m-ke) on CodePen.
論理積(&&)の挙動について
論理積(&&)は、左辺の値がFalseになったらその時点で値を返し、それ以降の判定は無視されます。
例えば、次の条件式の場合はFalseが返ってきます。
上記は条件式の判定を比較演算の結果にしています。この場合、結果はFalseになります。
この条件式を変数に格納すると、結果的にはfalseが格納され、if文で条件判定すると、結果はFlaseになることが確認できます。
const conditions = 10 < 0 && 10 < 20; //変数にfalseが格納される
if(conditions) {
return "Trueでした"; // 無視される
} else if(!conditions) {
return "Falseでした"; // 返却される
}
次は、先ほどのように比較演算でなく、値を条件式に指定した場合です。
左辺の値がTrueだと、右辺の値が返却されます。False判定された値がそのまま返却されます。
この場合、変数「conditions」には空文字が格納され、if文の判定はFalseになります。
const conditions = "テスト" && ""; //変数に空文字が格納される
if(conditions) {
return "Trueでした"; // 無視される
} else if(!conditions) {
return "Falseでした"; // 返却される
}
条件式の数が増えても同様で、左から順番に判定して、Falseになった時点でその値を返却し、それ以降の判定は無視されます。
const conditions = 10 && null && 20; //変数にnullが格納される
if(conditions) {
return "Trueでした"; // 無視される
} else if(!conditions) {
return "Falseでした"; // 返却される
}
判定が全てTrueになった場合、一番右側の値が返却されます。
この場合、一番右側の20が返却されるので条件判定はTrueになります。
const conditions = 10 && 15 && 20; //変数に20が格納される
if(conditions) {
return "Trueでした"; // 返却される
} else if(!conditions) {
return "Falseでした"; // 無視される
}
実際の判定結果はこちらで確認できます!
See the Pen && by donguri2020 (@m-ke) on CodePen.
論理和(||)の挙動について
論理和(||)は論理積と逆で、左辺の値がTrueになったらその時点で値を返し、それ以降の判定は無視されます。
例えば、次の条件式の場合はTrueが返ってきます。
上記の条件式も判定を比較演算の結果にしています。この場合、結果はTrueになります。
この条件式を変数に格納すると、結果的にはtrueが格納され、if文で条件判定すると、結果はTrueになることが確認できます。
const conditions = 10 < 20 || 10 < 0; //変数にtrueが格納される
if(conditions) {
return "Trueでした"; // 返却される
} else if(!conditions) {
return "Falseでした"; // 無視される
}
次は、先ほどのように比較演算でなく、値を条件式に指定した場合です。
左辺の値がFalseだと、右辺の値が返却されます。
この場合、変数「conditions」には「てすと」の文字列が格納され、if文の判定はTrueになります。
const conditions = "" || "てすと"; //変数に「てすと」の文字列が格納される
if(conditions) {
return "Trueでした"; // 返却される
} else if(!conditions) {
return "Falseでした"; // 無視される
}
条件式の数が増えても同様で、左から順番に判定して、Trueになった時点でその値を返却し、それ以降の判定は無視されます。
const conditions = null || 10 || 0; //変数に10が格納される
if(conditions) {
return "Trueでした"; // 返却される
} else if(!conditions) {
return "Falseでした"; // 無視される
}
判定が全てFalseになった場合、一番右側の値が返却されます。
この場合、返却される値が0なので、条件判定はFalse になります。
const conditions = null || 0 || 0; //変数に0が格納される
if(conditions) {
return "Trueでした"; // 無視される
} else if(!conditions) {
return "Falseでした"; // 返却される
}
実際の判定結果はこちらで確認できます!
See the Pen JavaScriptOR by donguri2020 (@m-ke) on CodePen.
論理和(||)で初期値を設定する
論理和(||)で時々見かける使い方についてメモしておきます。
例えば、以下のように挨拶を返す関数があるとして、引数greetingの値がない場合、初期値を決めておきたい!とします。
ポイントは色付けしている変数greetingTextに代入している論理和(||)です。
// 挨拶を返す関数
function fc(name, greeting) {
// 引数greetingに値がなければ「こんにちは」が変数に格納される
const greetingText = greeting || "こんにちは";
return `${greetingText}。${name}さん`;
}
console.log(fc("マイク", "ハロー")); // ハロー。マイクさん
console.log(fc("花子")); // こんにちは。花子さん
論理和(||)を使えば、引数greetingに値があれば引数の値が変数に格納され、値がない場合はFalse判定となるので、右側の値「こんにちは」が変数に格納されることになります。
if文で判定することもできますが、論理和(||)を使うことでスッキリ記述することができます!
Null 合体演算子(??)の挙動について
Null 合体演算子(??)は、左辺がnull または undefinedの場合だけ右辺を返却します。左辺の値が、null または undefined以外の場合は左辺を返却します。
以下の場合、左辺の値がnullなので、右辺の値(正の数字20)が返却されます。
論理和(||)との違い
論理和(||)の挙動と少し似ていますが、論理和は、左辺の値がFalseの場合、右辺の値を返却します。
False判定されるのは、null、undefined以外に0(数字)やNaN、空文字も含まれます。
論理和はこれらの値が左辺にある場合、右辺の値を返却します。
Null 合体演算子(??)はnull または undefinedの場合だけ右辺の値を返却します。
以下の場合、左辺は0(数字)でFalseですが、右辺ではなく、左辺の値0(数字)が返却されます。
論理否定(!)の挙動について
論理否定(!)は実際の判定の逆を返します。
判定がTrueの場合はFalse を返し、Falseの場合はTrue を返します。
判定の逆を返すので、スイッチのような動きを実装したい時によく使います。
簡単なサンプルを作りました。
See the Pen CountUp by donguri2020 (@m-ke) on CodePen.
ボタンをクリックするとカウントアップし、3か15の倍数の時にスイッチがオンになります。
スイッチのオンオフの部分だけ抜き出したコードがこちらです。
const countUpBtn = document.getElementById("countUpBtn");
const icon = document.getElementById("icon");
let flag = false; // オンオフ判定のフラグ
// スイッチオンオプ
const showIcon = (flag) => {
if(flag) {
icon.innerHTML = '<i class="fas fa-toggle-on"></i>';
} else {
icon.innerHTML = '<i class="fas fa-toggle-off"></i>';
}
}
// ボタンクリック
countUpBtn.addEventListener('click', () => {
showIcon(flag);
if(addNum % 15 == 0) {
showIcon(!flag);
} else if(addNum % 3 == 0) {
showIcon(!flag);
} else if(addNum % 5 == 0) {
showIcon(!flag);
}
});
さらに細かくみていきます。まずオンオフを判定する変数を設定します。
初期値はFalseです。
// オンオフ判定のフラグ
let flag = false;
スイッチのオンオフの切り替えをする関数showIconを作成します。
引数flagの値がTrueならオンにしてFalseならオフにします。
// スイッチオンオプ
const showIcon = (flag) => {
if(flag) {
icon.innerHTML = '<i class="fas fa-toggle-on"></i>';
} else {
icon.innerHTML = '<i class="fas fa-toggle-off"></i>';
}
}
カウントアップのボタンをクリックした時、スイッチのオンオフの切り替えをする関数showIconを実行しますが、引数のflagを論理否定(!)で渡すと、現状のflagの逆の状態を渡すことになります。結果的にオンオフが実装できます。
// ボタンクリック
countUpBtn.addEventListener('click', () => {
showIcon(flag); // 該当しない数字の場合False
if(addNum % 15 == 0) {
showIcon(!flag); // Falseの反対Trueを引数で渡す
} else if(addNum % 3 == 0) {
showIcon(!flag); // Falseの反対Trueを引数で渡す
} else if(addNum % 5 == 0) {
showIcon(!flag); // Falseの反対Trueを引数で渡す
}
});
まとめ
なんとなく使っていた論理演算子を改めてまとめました。
基礎中の基礎とはいえ、意外と分かっていない部分もあったのでスッキリしました。
特に変数の代入ではコードがスッキリかけます。今後も積極的に使っていきたいと思います!
コメント