strict mode を意識する

生田 陸人
LuaGate エンジニア / 現役エンジニア
編集 LuaGate編集部

strict mode を意識する とは

JavaScript の落とし穴を防ぐ厳格な比較 === を使って、値が一致するか判定しよう。本レッスンでは、strict mode を意識する の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。

なぜ JavaScript には strict mode があるのか

JavaScript は 1995 年に「10 日間で作られた」と言われるくらい、急ぎ足で誕生した言語です。そのせいで、後から見ると「これは罠だ…」という機能がいくつか残っています。たとえば変数を宣言しなくても name = "Alice"; と書けばグローバル変数が勝手にできる、==0 == "0"true になる、などです。

これらの罠を回避するために、ES5 (2009 年) で strict mode という機能が導入されました。ファイルの先頭 (または関数の先頭) に "use strict"; と書くと、JavaScript がより厳格に動いてくれます。

JavaScript

"use strict"; function add(a, b) { return a + b; }

さらに、ES2015 (ES6) 以降の module (import export を使うファイル) では、何も書かなくても自動的に strict mode で動きます。chotdekiru のエディタや最新のフレームワークでは、ほぼ常時 strict mode 相当だと思って大丈夫です。

strict mode を「邪魔な機能」と思う人もいますが、実際には「壊れた電車を線路に戻すための安全装置」です。最初から strict で書くクセを付けると、後で大規模なリファクタリングをするときに楽です。

===== の違い

strict mode と並んでよく出てくる「厳格」のキーワードが、比較演算子の === です。JavaScript には等しいかどうかを比べる演算子が 2 種類あります。

JavaScript

console.log(1 == "1"); // => true (型を無視して比較) console.log(1 === "1"); // => false (型まで一致する必要がある) console.log(0 == false); // => true console.log(0 === false); // => false

== は両側の型をなんとなく合わせてから比較するので、1 == "1" のような直感に反する結果になります。一方、=== は型まで含めて厳密に比較するので、数値の 1 と文字列の "1" は別物として false になります。

現代の JavaScript では、特別な理由がない限り ===!== だけを使う のがベストプラクティスです。== を使うのは、nullundefined を両方チェックしたいときの value == null くらいで十分です。

比較の流れを図で見る

===== の処理の違いを図で見てみましょう。

diagram (will load when visible)

== は途中で「型をそろえる」というステップを挟むため、意図しない場所で true になってしまいます。=== は「型が違うなら即 false」と判断するので、結果が予測しやすいのです。

厳格モードで救われる例

strict mode と === を使うと、どんなバグが防げるのかを具体例で見てみましょう。

JavaScript

// strict mode なし function sloppy() { total = 100; // var/let/const なしで変数を作るとグローバル汚染 return total; } // strict mode あり "use strict"; function strict() { total = 100; // ReferenceError: total is not defined return total; }

上のコードは strict mode なしだとそのまま動いてしまい、total がグローバル変数として勝手に作られます。strict mode ありだとエラーで止まるので、「あ、let total を書き忘れた」と早めに気付けます。

JavaScript

// === なら型違いに気付ける const userId = 1; const params = { id: "1" }; // URL から取れた文字列 if (userId === params.id) { console.log("一致"); } else { console.log("不一致"); // こちらが表示される }

== で書いていたら気付かないところを、=== だと「型が違う」と教えてくれます。Number(params.id) で明示的に変換するなど、対処も明確になります。

よくある間違い

strict mode 周りの落とし穴を 3 つ紹介します。

  • == のクセが抜けないPythonPHP から来た人がよく書き間違えるパターン。=== を機械的に使う習慣を付けましょう。エディタの設定で == を警告にすると効果的です
  • NaN === NaNfalse=== でも NaN (Not a Number) は自分自身と等しくない、という特殊ルールがあります。Number.isNaN(value) を使って判定しましょう
  • "use strict" の位置が間違っている"use strict"; はファイルの 先頭 または関数の 先頭 に書く必要があります。途中に書くと無視されます

もうひとつの罠が、オブジェクト同士の === です。{} === {}false になります。=== はプリミティブ値だけ「値が同じか」、オブジェクトは「参照が同じか」を比べるからです。中身を比べたいなら JSON.stringify を使うか、ライブラリを使います。

やってみよう

それでは課題に挑戦しましょう。関数 isExactlyEqual を作って、引数 2 つを厳密に比較する関数を書きます。

  1. 引数 ab を受け取る
  2. === で比較して、結果を return する
  3. 戻り値は truefalse の真偽値になる

isExactlyEqual(1, 1)trueisExactlyEqual(1, "1")falseisExactlyEqual("abc", "abc")trueisExactlyEqual(0, false)false を返します。型まで一致する必要がある、という点を意識してください。

慣れてきたら、== で書いた場合の結果と比べてみると違いがはっきり見えてきます。本番のコードでは原則 ===、と覚えておきましょう。

よくある質問

Q. ブラウザと Node.js で動作は変わりますか?

A. JavaScript の構文・組み込み機能(配列・文字列・Promise 等)はどちらでも同じです。違いは DOM API(ブラウザ専用)と fs などのファイル系(Node 専用)など、実行環境固有の機能です。コアロジックは両方で動くため、テストもしやすくなります。

Q. ES6 以降の新機能は使っても大丈夫ですか?

A. 現代のブラウザ・Node.js は ES2020 以降の機能をほぼサポートしています。古い IE 等を対象にする必要が無ければ、let/const、アロー関数、分割代入、async/await を積極的に使ってください。トランスパイル(Babel/Vite)が必要なケースは年々減っています。

Q. TypeScript に進む価値はありますか?

A. 型情報があるとリファクタやエディタ補完が劇的に効くため、規模が大きくなるなら TypeScript への移行を強くおすすめします。最初は any を許容しつつ徐々に型を付ければ、JS の知識をそのまま活かせます。

次のレッスン

次は 複数の戻り値パターン で、JavaScript の落とし穴を防ぐ厳格な比較 === を使って、値が一致するか判定しよう を学びます。

事前確認 — 進む前に次の 3 つができることを確認しましょう。

  1. strict mode の要点を自分の言葉で説明できる
  2. このレッスンの最小コード (または操作手順) を見ずに書ける
  3. 練習問題やクイズで間違えた箇所を読み直して理解した

理解度チェック (30 秒)

Q. strict mode とは何か、1 文で説明してください。

この章のポイント

A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。

関連レッスン

要件

  1. 関数名は isExactlyEqual、引数は ab の 2 つ
  2. 比較演算子は === を使うこと (== は禁止)
  3. 戻り値は真偽値 (truefalse)

入出力例

test-cases.txt

isExactlyEqual(1, 1)true isExactlyEqual(1, "1")false isExactlyEqual("abc", "abc")true isExactlyEqual(0, false)false isExactlyEqual(true, true)true

ヒント

main.js
main.js
学習モード

メモ

strict mode を意識する

⌘S で保存