JavaScript | 基礎構文:比較・論理 – falsy / truthy

JavaScript JavaScript
スポンサーリンク

falsy / truthy を一言でいうと

JavaScript の falsy / truthy は、
「if 文などで、その値が “偽っぽい” か “真っぽい” か」 を表す言葉です。

if (値) { ... } と書いたとき、
その「値」が truefalse そのものじゃなくても、
JavaScript は勝手に「これは偽っぽい(falsy)」「これは真っぽい(truthy)」と判断して動きます。

ここが重要です。
あなたが if (value) と書いた瞬間、
JavaScript は value を「真偽値として解釈」しはじめます。
そのときのルールを「falsy / truthy」として覚えておくと、
条件式で迷子になる回数がガクッと減ります。


falsy とは何か(偽っぽい値たち)

falsy になるのはこの 6 つだけ

JavaScript で「falsy(条件で false とみなされる)」になる値は、
実は決まったものだけです。

false
0
""(長さ 0 の空文字列)
null
undefined
NaN

この 6 つ以外は、基本すべて truthy(真っぽい)です。

例えば次の if 文を見てください。

if (0) {
  console.log("実行されない");
}

if ("") {
  console.log("実行されない");
}

if (null) {
  console.log("実行されない");
}

if (undefined) {
  console.log("実行されない");
}

if (NaN) {
  console.log("実行されない");
}

if (false) {
  console.log("もちろん実行されない");
}
JavaScript

どれも何も表示されません。
全員 falsy だからです。

「falsy だからダメ、truthy だから良い」ではない

勘違いしがちなのが、
「falsy =悪い」「truthy =良い」ではない、という点です。

例えば 0 は falsy ですが、
スコアや金額としては普通に有効な値です。

const score = 0;

if (score) {
  console.log("スコアあり");
} else {
  console.log("スコアなし扱いになってしまう"); // 0 は falsy なのでこちら
}
JavaScript

このコードは「0 点なのに “スコアなし” と扱ってしまう」バグの元です。

ここが重要です。
falsy / truthy は「値の意味」ではなく「条件式の中でどう解釈されるか」の話。
「0 を偽とみなしていいのか?」「空文字を未入力扱いしていいのか?」を、その都度ちゃんと考える必要があります。


truthy とは何か(それ以外は全部こっち)

falsy 以外は全部 truthy

さきほどの 6 つ以外は、すべて truthy です。

たとえば次はぜんぶ truthy です。

true
"0"(文字列のゼロ)
" "(空白だけの文字列)
"hello"
-1
3.14
[](空配列)
{}(空オブジェクト)
function() {}(関数)

実際に if で試してみると分かります。

if ("0") {
  console.log('"0" は truthy'); // 実行される
}

if (" ") {
  console.log('" "(空白)は truthy'); // 実行される
}

if ([]) {
  console.log("[] は truthy"); // 実行される
}

if ({}) {
  console.log("{} は truthy"); // 実行される
}
JavaScript

「空配列」「空オブジェクト」も truthy なのを忘れない

ここは特にハマりやすいところです。

「配列が空かどうか」を、
ついこう書いてしまいがちです。

const arr = [];

if (!arr) {
  console.log("空配列だと思ってしまう");
}
JavaScript

しかし [] は truthy なので、
!arrfalse になり、この if は実行されません。

空配列かどうかを調べたいときは、
長さで判定します。

if (arr.length === 0) {
  console.log("空配列です");
}
JavaScript

オブジェクトも同じで、
空かどうかを falsy / truthy では判断できません。

ここが重要です。
「空配列」「空オブジェクト」は truthy。
“中身があるかどうか” を falsy / truthy で判断しようとすると事故ります。
中身の有無は length やキーの数で判定する、と覚えておいてください。


if 文の中では、何が起きているのか

if (値) は Boolean(値) と同じように扱われる

次の 2 つは、ほぼ同じ意味だと思ってください。

if (value) { ... }

if (Boolean(value)) { ... }
JavaScript

つまり if に書いた値は、
内部的には「真偽値に変換されて」から
true / false として扱われています。

Boolean で実験してみると分かりやすいです。

console.log(Boolean(0));         // false
console.log(Boolean(""));        // false
console.log(Boolean(null));      // false
console.log(Boolean(undefined)); // false
console.log(Boolean(NaN));       // false

console.log(Boolean("0"));       // true
console.log(Boolean(" "));       // true
console.log(Boolean([]));        // true
console.log(Boolean({}));        // true
JavaScript

この結果が、そのまま
「if に書いたときに中に入るかどうか」になります。

ここが重要です。
if 文の条件は「boolean 型かどうか」ではなく、「truthy か falsy か」で判断される。
つまり、あらゆる値が最終的に Boolean(value) として評価されてから、
実行するかどうかが決まっています。


!!(二重 NOT)で「true / false」に落とし込む

!!value は「truthy / falsy を真偽値に変える」

!!value は、
「その値が truthy か falsy かを、はっきり true / false にしたいとき」 に使う小技です。

console.log(!!"hello");   // true
console.log(!!"");        // false
console.log(!!0);         // false
console.log(!!123);       // true
console.log(!!null);      // false
console.log(!!{});        // true
JavaScript

1 回目の ! で「反転」し、
2 回目の ! で再度反転して、
最終的に「純粋な真偽値」だけが残ります。

「フラグ」を作るときに便利

例えば「名前が設定されているかどうか」を、
真偽値のフラグとして持っておきたいとします。

const name = "太郎";

const hasName = !!name;

if (hasName) {
  console.log("名前ありの処理");
}
JavaScript

name が空文字 "" のときは、
!!name は false になるので、
hasName は「名前が実質的にあるかどうか」という意味の boolean になります。

ここが重要です。
!! 自体はトリッキーな見た目ですが、
「truthy / falsy の結果を、ちゃんと true / false に落とし込む」という役割があります。
“状態を表すフラグ” を作るとき、
const isXxx = !!value; という形にまとめておくと、
後のコードがだいぶ読みやすくなります。


論理演算子と falsy / truthy の関係

||(論理 OR)と falsy

論理 OR || は、

「左が truthy なら左を返し、
左が falsy なら右を返す」

という性質があります。

console.log("" || "default");    // "default"(左が falsy なので右)
console.log("hello" || "default"); // "hello"(左が truthy なので左)

console.log(0 || 10);    // 10(0 は falsy)
console.log(5 || 10);    // 5(5 は truthy)
JavaScript

よくある「デフォルト値」のパターンです。

const input = "";
const name = input || "名無しさん";

console.log(name); // "名無しさん"
JavaScript

ただし 0 や空文字を「有効な値」としたいときは注意

例えば数値入力で、
0 も立派な有効値だとします。

const input = 0;
const value = input || 100;

console.log(value); // 100 になってしまう
JavaScript

0 は falsy なので、
input || 100 は 100 になってしまいます。

この場合は || に頼らず、明示的にチェックする必要があります。

ここが重要です。
論理 OR と falsy / truthy を組み合わせた「楽な書き方」は強力ですが、
「0 や空文字も立派に有効」という場面では、
それらまで falsy として扱っていいのかを必ず自分に問い直してください。


実務での考え方:「まとめて雑に」か「丁寧に区別する」か

まとめて雑に扱っていい場面

例えば、「未入力・0・空白・null・undefined・NaN」
そういうのを全部まとめて「実質的に空」と見なしたいとき。

const value = getUserInput();

if (!value) {
  console.log("実質的に空の入力と扱う");
}
JavaScript

この if は、value が falsy のすべての場合に反応します。
フォーム入力の「とりあえず何か入っていれば OK」くらいのチェックなら、
これで済ませてもよい場面はあります。

むしろちゃんと区別すべき場面

逆に、「0 は有効な値」「空文字は意味がある」「null と undefined は分けたい」
こういう場面では、falsy / truthy に丸投げすべきではありません。

// 悪い例
if (!score) {
  console.log("スコアがありません"); // 0 まで「ありません」にされてしまう
}

// 良い例(例1:null/undefined 判定)
if (score === null || score === undefined) {
  console.log("スコアが未設定です");
}

// 良い例(例2:typeof で数値かどうか)
if (typeof score === "number") {
  console.log("数値スコアがあります(0 を含む)");
}
JavaScript

ここが重要です。
falsy / truthy は、「ざっくり“空っぽ系”をまとめて扱いたいとき」の道具です。
「0 はダメじゃない」「空文字も意味がある」という文脈では、
falsy / truthy に頼らず、値をきちんと区別する条件を書くべきです。


初心者として falsy / truthy で本当に押さえてほしいこと

falsy になるのは
false, 0, "", null, undefined, NaN の 6 つだけ。
それ以外は基本的に全部 truthy。

if (value) は、内部的には if (Boolean(value)) のように評価される。
条件式は「真偽値かどうか」ではなく「truthy か falsy か」で判断される。

空配列 [] や空オブジェクト {} も truthy。
“中身があるかどうか” を falsy / truthy で判定しようとするとバグになる。

!!valueBoolean(value) で、「truthy / falsy の結果」を純粋な true / false に変換できる。
フラグを作るときに便利だが、0 や空文字まで false になる点には注意。

ここが重要です。
falsy / truthy は、JavaScript が「値をどう解釈するか」のレンズです。
if 文や || / && を書くたびに、
“この値が 0 や空文字のとき、自分はどう扱いたい?” と一瞬だけ考える。
その癖がつくと、条件式が一気に「自分の意図とズレない」ものになっていきます。

最後に、小さな練習を置いておきます。
結果を予想してから実行してみてください。

const values = [
  false,
  true,
  0,
  1,
  -1,
  "",
  "0",
  " ",
  "hello",
  null,
  undefined,
  NaN,
  [],
  {},
];

for (const v of values) {
  console.log(
    JSON.stringify(v),
    "=> Boolean:", Boolean(v)
  );
}
JavaScript

「自分の直感」と「Boolean の結果」がズレたところが、
あなたと JavaScript の falsy / truthy のギャップです。
そこを一つずつ潰していくことが、条件式を思い通りに操る第一歩になります。

タイトルとURLをコピーしました