3.

JavaScript Booleanの基礎|Truthy・Falsy・!!・filter(Boolean)

編集
この記事の要点
  • JavaScript の Boolean 値は true / false の 2 値。プリミティブ型
  • Falsy 値は 7 種: false / 0 / -0 / 0n / "" / null / undefined / NaN。それ以外は全部 Truthy([]{} も true!)
  • !!value で任意値を Boolean に変換するイディオム(Boolean(value) でも可)
  • == ではなく === を使う。0 == falsetrue になり事故る
  • arr.filter(Boolean) は配列から Falsy を一掃する定番テクニック

true / false の基本

const isOpen = true;
const isAdmin = false;

typeof isOpen;     // "boolean"

// 否定演算子
!isOpen;           // false
!!isOpen;          // true(boolean に正規化するイディオム)

// 論理演算子
true && 'A';       // 'A' (AND は左が真なら右を返す)
false && 'A';      // false
true || 'A';       // true
false || 'A';      // 'A'  (OR は左が偽なら右を返す)

// Nullish Coalescing は null/undefined のときだけ右
0 || 'default';    // 'default'
0 ?? 'default';    // 0  ← 0 は null/undefined ではないので残る

Truthy / Falsy の完全リスト

JavaScript の Falsy はちょうど 7 種類です。それ以外は全て Truthy:

Boolean 化備考
falsefalse言わずもがな
0 / -0false数値ゼロ
0nfalseBigInt の 0
""false空文字
nullfalse
undefinedfalse
NaNfalse
"false"true★ 文字列なので真!
"0"true★ 文字列なので真!
[]true★ 空配列も真
{}true★ 空オブジェクトも真
関数true

確認

// if 文の判定ルール
if (0) console.log('a');         // 出ない
if ('0') console.log('b');       // 出る ← 文字列
if ([]) console.log('c');        // 出る ← 空配列
if ({}) console.log('d');        // 出る ← 空オブジェクト
if (null) console.log('e');      // 出ない
if (undefined) console.log('f'); // 出ない

// Boolean(x) で確認
Boolean([]);       // true
Boolean({});       // true
Boolean('0');      // true
Boolean('false');  // true
Boolean(0);        // false
Boolean('');       // false

Boolean 化のイディオム

// 関数呼び出し
Boolean('hello');     // true
Boolean(0);           // false

// !! (NOT を 2 回 = Boolean 化) ← 短くて速い
!!'hello';            // true
!!0;                  // false
!!null;               // false
!!{};                 // true

// よく使うパターン: API レスポンスの「ある/ない」を返す
function hasError(res) {
  return !!res.error;
}
hasError({ error: 'NG' });   // true
hasError({ error: null });   // false
hasError({});                // false

// TypeScript で boolean 型を返したいとき
function isAdult(age?: number): boolean {
  return !!age && age >= 18;
  // age が undefined なら false、数値で 18 以上なら true
}

== vs ===

論理値が絡む比較では必ず ===== は型変換が入り、直感に反する挙動になります:

// ❌ == の罠
0 == false;          // true
'' == false;         // true
'0' == false;        // true("0" → 0 → false)
[] == false;         // true([] → '' → 0 → false)
null == undefined;   // true
1 == true;           // true
2 == true;           // false!(true → 1 だが 2 とは違う)

// ✅ === なら全部 false(型が違う)
0 === false;         // false
'' === false;        // false
null === undefined;  // false

filter(Boolean) で Falsy を一掃

配列から Falsy を取り除く最短イディオム:

const arr = [0, 1, '', 'a', null, 'b', undefined, NaN, 'c', false];
const cleaned = arr.filter(Boolean);
// ['a', 'b', 'c']  ← Falsy 全部消える

// CSS クラスを条件付きで組み立てるテク
const classes = [
  'btn',
  isPrimary && 'btn-primary',
  isLarge && 'btn-lg',
  isDisabled && 'btn-disabled',
].filter(Boolean).join(' ');

// → "btn btn-primary btn-lg" のように条件のものだけ残る

// Optional な値の配列を作るとき
const result = [
  user && getUserData(user),
  org && getOrgData(org),
].filter(Boolean);

every と some

const flags = [true, true, false];

flags.every(Boolean);    // false(全部 true ではない)
flags.some(Boolean);     // true(少なくとも 1 つ true)

// 全部正の数か
[1, 2, 3].every(n => n > 0);     // true
[1, -2, 3].every(n => n > 0);    // false

// 1 つでも空文字を含むか
['a', '', 'c'].some(s => s === '');  // true

// every の罠: 空配列に対しては true(数学的な「Vacuous truth」)
[].every(() => false);    // true!
[].some(() => true);      // false

Boolean() と new Boolean() の違い

// ✅ 関数呼び出し: プリミティブ boolean
const a = Boolean('hi');
typeof a;          // "boolean"
a;                 // true

// ❌ new でラッパーオブジェクト(非推奨)
const b = new Boolean(false);
typeof b;          // "object"
if (b) console.log('真!');  // ★ 出る!

// なぜ: オブジェクトは Truthy なので、new Boolean(false) でも if は真
// → new Boolean() は絶対に使わない

// 同様に new String / new Number も避ける

三項演算子と短絡評価

// 三項
const label = isAdmin ? '管理者' : '一般';

// 短絡で条件レンダリング(React)
return (
  <div>
    {isLoading && <Spinner />}
    {error && <ErrorMsg msg={error} />}
    {!isLoading && !error && <Content />}
  </div>
);

// ⚠️ React で 0 が描画される罠
{items.length && <List />}      // items.length が 0 のとき "0" が画面に出る
{items.length > 0 && <List />}  // ✅ こちらが安全
{!!items.length && <List />}    // ✅ Boolean 化でも OK

TypeScript での Type Predicate

// Boolean を返すユーザ定義型ガード
function isString(x: unknown): x is string {
  return typeof x === 'string';
}

const mixed: (string | number)[] = ['a', 1, 'b', 2];
const strs = mixed.filter(isString);
// strs の型は string[] と推論される

// filter(Boolean) は型が消える問題がある
const arr: (string | null)[] = ['a', null, 'b'];
const r = arr.filter(Boolean);
// r の型は (string | null)[] のまま! ← TS は推論しきれない
// → ユーザ定義型ガードを使う
const r2 = arr.filter((x): x is string => x !== null);
// r2: string[]

FAQ

Q: !!xBoolean(x)、どちらが良い?
A: 動作は同じ。!! は短くて多用される、Boolean() は意図が明示的で読みやすい。ESLint のルール次第で統一する。

Q: "false" 文字列を boolean に変換したい
A: Boolean()!! ではダメ(true になる)。str === 'true' で明示判定するか JSON.parse(str)

Q: NaN === NaN は?
A: false。NaN は自分自身とも等しくない。判定は Number.isNaN(x) または Object.is(x, NaN)

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. JSON
  2. Array
  3. Boolean(JavaScriptビルトイン)
  4. Date オブジェクト
  5. Math (JS ビルトイン)
  6. Number
  7. Object(JavaScriptビルトイン)
  8. RegExp

最近更新/作成されたページ