論理演算子と短絡評価
このレッスンで分かること
&&(かつ)、||(または)、!(〜でない)で条件を組み合わせます&&と||は真偽値ではなく、左右のどちらかの値そのものを返します
条件がひとつで済むことはめったにない
プロフィールサイトに作品を並べるとき、判定はたいてい重なります。「作品のデータが届いていて、かつ公開中のときだけ表示する」のように、複数の条件を組み合わせたい。これを担当するのが論理演算子です。
| 演算子 | 読み方 | 意味 | 例 |
|---|---|---|---|
&& | アンド | 両方が真のとき真 | hasPhoto && likes >= 100 |
|| | オア | どちらかが真なら真 | isPinned || hasPhoto |
! | ノット | 真偽を反転する。返るのは必ず true か false | !isPinned |
JavaScript
const hasPhoto = true;
const likes = 120;
console.log(hasPhoto && likes >= 100); // true 両方満たす
console.log(hasPhoto && likes >= 200); // false 右が偽
console.log(hasPhoto || likes >= 200); // true 左が真
console.log(!hasPhoto); // false 反転返るのは true / false ではなく値そのもの
ここが JavaScript の論理演算子でいちばん大事なところです。&& と || は真偽値を作って返しているのではなく、左右のオペランドのどちらかをそのまま返しています。
JavaScript
console.log("プロフィール" && "作品一覧"); // 作品一覧
console.log("" && "作品一覧"); // 空文字
console.log("プロフィール" || "作品一覧"); // プロフィール
console.log(0 || 120); // 120ルールは 2 つだけです。A && B は A が falsy なら A を、truthy なら B を返します。A || B は A が truthy なら A を、falsy なら B を返します。第2章で扱った falsy の感覚が、そのまま論理演算子の挙動の理解につながります。
値そのものが返るということは、戻り値が boolean とは限らないということです。関数から真偽を返したいときは Boolean() で包んで形をそろえます。包み忘れると、=== false で比べているコードからは見えないバグになります。
!を 2 つ重ねた!!valueという書き方もあります。反転の反転なのでBoolean(value)と同じ意味ですが、読みやすいのはBooleanのほうです。新しく書くならこちらを使ってください。
左辺で決まると右辺は読まれない
&& と || は、左辺だけで結果が確定した時点で右辺の評価をやめます。これを短絡評価と呼びます。
JavaScript
function log(value) {
console.log("評価された", value);
return value;
}
false && log("右辺"); // 何も表示されない
true || log("右辺"); // 何も表示されない
true && log("右辺"); // 評価された 右辺単なる最適化ではなく、意図して使うテクニックでもあります。たとえば、閲覧数の合計を作品数で割る前に、作品数が 0 でないことを確かめます。
JavaScript
const total = 120;
const count = 0;
console.log(count && total / count); // 0 割り算は実行されないcount が 0 のとき、左辺が falsy なので右辺の割り算は行われず、0 が返ります。count が 3 なら右辺が評価され、40 が返ります。このように、左側の条件を満たすときだけ右側の処理を行う書き方を「ガード」と呼びます。
演習では、作品があるかどうかと公開状態の取り出しをひな形が済ませています。準備された値を使い、条件を組み合わせる部分と Boolean() による変換を自分で書きます。
よくある間違い
&&の戻り値を boolean だと思い込む —likes && likes >= 100は、likesが0のとき0を返します。falseではありません
JavaScript
console.log(0 && true); // 0
console.log(Boolean(0 && true)); // falsea === 1 || 2と書く — 「a が 1 または 2」のつもりでも、2は truthy なので式全体が常に truthy になります。a === 1 || a === 2のように、比較を 2 回書いてください
要件
- 関数名は
isVisible、引数はworkの 1 つのままにすること - 準備済みの
hasWorkとpublishedを&&で組み合わせ、その結果を変数に入れること - 組み合わせた結果を
Boolean()で真偽値に変換し、別の変数に入れること - 変換した値を
returnで返すこと。作品がないときもエラーにせずfalseを返すこと