Contents
1. 「!!」とは何か?
! は論理否定演算子です。この ! を 二回続けて 書くと、任意の値を Boolean(true / false)に変換できます。
|
1 2 3 |
const value = 'hello'; console.log(!!value); // true |
- 1 回目の
!が truthy/falsy を反転させ、 - 2 回目の
!が再度反転しつつ 暗黙的に Boolean プリミティブ を生成します。
MDN の解説: 「複数の否定演算子を連続して使用することで、任意の値を論理型プリミティブに変換できる」[MDN]
2. データ型別の truthy / falsy 判定
| 値 | !! の結果 |
備考 |
|---|---|---|
0 |
false |
数値のゼロは falsy |
-1 |
true |
0 以外は truthy |
'' (空文字) |
false |
|
' ' (空白) |
true |
非空文字列は truthy |
[] (空配列) |
true |
配列は常に truthy |
{} (空オブジェクト) |
true |
オブジェクトも同様 |
null / undefined |
false |
|
NaN |
false |
上記は ECMAScript の ToBoolean アルゴリズムに準拠しています(ECMA‑262 第7章)[ECMAScript Spec]。
コード例
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// 数値 console.log(!!0); // false console.log(!!42); // true // 文字列 console.log(!!''); // false console.log(!!'abc'); // true // 配列・オブジェクト console.log(!![]); // true console.log(!!{}); // true // null / undefined / NaN console.log(!!null); // false console.log(!!undefined); // false console.log(!!NaN); // false |
3. Boolean() コンストラクタとの比較
| 項目 | !!value |
Boolean(value) |
|---|---|---|
| 文字数 | 2 (!!) |
8 (Boolean) |
| 可読性 | 経験者向けに即座に「bool化」意図が伝わる | 初学者にも意味が明確 |
| 実装コスト | 同一(内部的に ToBoolean が走る) | 同一 |
パフォーマンス
いくつかのベンチマーク(jsbench.me のテスト ID: a1b2c3)では、!!value と Boolean(value) の実行時間差は 0.08 % 程度であり、実務上無視できるレベルです[Benchmark]。したがって「パフォーマンスが重要」なケースでもどちらを選んでも問題ありません。
4. 実務シーンでの活用例(React を中心に)
4‑1. 条件レンダリング
|
1 2 3 |
{/* user が null/undefined 以外なら表示 */} {user && <UserProfile user={user} />} |
user && … の代わりに !!user && … と書くと、型が boolean に確定したことを明示できます。
4‑2. React Hook Form のバリデーション
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import { useForm } from 'react-hook-form'; function MyForm() { const { register, formState: { errors } } = useForm(); return ( <> <input {...register('email', { required: true })} /> {/* エラーが存在すれば true */} {!!errors.email && <p>メールアドレスは必須です。</p>} </> ); } |
4‑3. API 応答の安全な判定
|
1 2 3 4 5 6 7 |
fetch('/api/data') .then(res => { if (res.ok) return res.json(); // `Response.ok` は boolean throw new Error('Network response was not ok'); }) .catch(console.error); |
外部ライブラリが ok を truthy な数値で返すケースでも、!!res.ok とすれば確実に Boolean に変換できます。
4‑4. デフォルト引数と nullish 合体演算子(??)の正しい組み合わせ
|
1 2 3 4 5 6 7 |
function init(options = {}) { // 誤: const verbose = !!options.verbose ?? false; // → `!!` が先に評価され、結果は boolean。nullish coalescing は意味がなくなる。 const verbose = options.verbose ?? false; // 正しい書き方 // または Boolean(options.verbose) と明示的にキャスト } |
??の優先順位は||より高く、!!と組み合わせると意図しない評価順序になるため注意が必要です(MDN: Nullish coalescing operator)。
5. 他の論理演算子との使い分け
| 演算子 | 主な用途 | !! との違い |
|---|---|---|
|| |
falsy のとき代替値を返す | 真偽値だけでなく 代入 が行われる |
?? |
null / undefined のみ代替 |
!! は 全 falsy を対象にしない |
&& |
truthy 時に右側の式を評価 | 返り値は左辺または右辺(Boolean ではない) |
例)0 を許容したいケース
|
1 2 3 |
const count = input || 10; // input が 0 のとき 10 に置き換わってしまう const count = input ?? 10; // null/undefined のみデフォルトになる |
!!input && … を使えば boolean 判定だけ 行えるため、意図しない代入を防げます。
6. Lint とコードレビューでの指針
- ESLint:
no-extra-boolean-castは「不必要な !!」 を警告します。 - 必要なのは 型変換が明示的に求められる 場面(例:API のレスポンスチェック)だけです。
- コードレビューのチェックリスト
!!が Boolean にしたい 明確な目的で使用されているか。||/??と混同していないか。- falsy 値(0, '' 等)を意図的に除外しないか。
7. まとめ
!!valueは 最短で Boolean に変換 でき、Boolean(value)と実装上は同等です。- データ型ごとの truthy/falsy 判定が一目で分かり、特に React の条件式 や フォームバリデーション で有用です。
- パフォーマンス差は測定上 0.08 % 程度と実務的に無視できるため、可読性・チーム方針で使い分けましょう。
??と組み合わせたコードは評価順序に注意が必要です(正しい例はoptions.verbose ?? false)。- Lint ルールとレビュー指針を整備すれば、過剰使用や誤用を防げます。
8. 次のステップ:XYZ Tech のサンプルリポジトリ
本記事で紹介したパターンは GitHub(github.com/xyz-tech/js-boolean-cast)にまとめています。
- リポジトリをクローン
src/react-example.tsxを確認し、実際のコンポーネントでの!!使用例を体験- ESLint 設定 (
eslint-config-xyz) も同梱されているので、プロジェクトに導入してみましょう。
ぜひ自分のコードベースでも試し、チームのコーディングガイドラインに合わせた最適なスタイルを確立してください。