【実務・中級編】【中級者向け】厳格モード(use strict)が変数の暗黙的宣言を許さない理由と利点 – JavaScriptコア文法・モダン言語仕様と変数・関数解析バイブル

厳格モード(`’use strict’`)が変数の暗黙的宣言を許さない理由と、モダンJS開発における真の価値

コードレビューをしていて、未だにファイルの先頭に `’use strict’;` が書かれていないレガシーなコードや、ビルドツールに依存しているからと油断してスコープの安全性をコンパイラ任せにしている現場に出くわすことがある。

テクニカルリードとして言わせてもらう。現代のフロントエンド開発において、厳格モードの理解と徹底は「あれば望ましい作法」ではなく、予測不能なメモリリークやスコープ汚染を防ぐための防衛ラインだ。

今回は、JavaScriptのエンジン内部(V8ランタイム)の挙動、そしてグローバルスコープの汚染がもたらす実務上の致命的なバグを引き合いに出しながら、なぜ「暗黙の変数宣言」が悪であり、厳格モードが必須なのかをロジカルに紐解いていこう。

—

1. なぜ「暗黙の変数宣言」はV8エンジンとメモリ管理の悪夢なのか?

JavaScript初学者の頃、あるいは急いでコードを書いている時に、こんなタイポをしたことはないだろうか。

function calculateTotal() {
// const や let を書き忘れた
totaol = price quantity;
return totaol;
}

`totaol` という痛恨のタイポ。厳格モード(`’use strict’`)が適用されていない環境では、このコードを実行してもエラーは起きない。代わりに何が起きるか?

JavaScriptエンジンは、現在のローカルスコープから上位スコープへ変数の宣言を遡って探し始める。しかし、どこにも `totaol` の宣言は見つからない。通常モード(Non-strict mode)において、エンジンはこの瞬間、自動的にグローバルオブジェクト(ブラウザなら `window`、Node.jsなら `global`)のプロパティとしてその変数を勝手に生み出す。

これが「暗黙のグローバル変数(Implied Globals)」の正体だ。

V8エンジンの隠しクラス(Hidden Classes / Shapes)への悪影響

V8などのモダンなJSエンジンは、オブジェクトのプロパティアクセスを高速化するために「隠しクラス(インラインキャッシュ)」という最適化メカニズムを使っている。

グローバルオブジェクトに予期せぬ動的プロパティが後から突然追加されると、エンジンはそのグローバルオブジェクトの構造(レイアウト)が変化したとみなす。これにより、グローバルオブジェクトに依存するすべてのプロパティアクセスの最適化が無効化(Deoptimization)され、コード全体の実行パフォーマンスが静かに、しかし確実に低下していく。

さらに厄介なのはメモリ管理だ。意図せずグローバルオブジェクトにぶら下がった変数は、アプリケーションがライフサイクルを終えて破棄されるまでガベージコレクション(GC)の対象から外れる。これが、SPA(Single Page Application)の画面遷移を繰り返すうちにメモリ消費量が右肩上がりに増えていく、いわゆる「見えないメモリリーク」の温床となるのだ。

—

2. 厳格モード(`’use strict’`)がもたらす静的な安全性

ES5で導入された厳格モードは、JavaScriptの言語仕様における「緩すぎる挙動」を強制的に矯正するためのスイッチである。

これをモジュール(ES Modules)や関数の先頭に宣言するだけで、JavaScriptエンジンはパーサーの段階から厳格なチェックを行うようになる。

‘use strict’;

function processOrder() {
// ReferenceError: totaol is not defined
totaol = 100 2;
}

タイポした瞬間に `ReferenceError` がスローされる。「実行時エラーに気づくのが早ければ早いほど、修正コストはゼロに近づく」。これはソフトウェア工学の鉄則だ。テストコードを書くまでもなく、エディタの静的解析やブラウザのコンソールを開いた瞬間にバグが爆ぜてくれるため、本番環境へのデプロイ事故を未然に防ぐことができる。

—

3. 【実践】保守性の高いモダンJSコード設計

では、実際のフロントエンド開発やAPI連携の現場において、厳格モードと安全な変数スコープを前提とした「美しく堅牢なプロダクションコード」の書き方を確認しよう。

以下のコードは、非同期APIからユーザーデータを受け取り、DOMを安全に操作しつつ、状態をカプセル化するモジュールの例だ。

/

  • ユーザープロファイル管理モジュール
  • @module UserProfileManager

/
‘use strict’;

// グローバル汚染を完全に防ぐための即時関数(IIFE)またはESモジュール構造
// ※現代のバンドラ(Vite / Webpack)環境ではESMを使うためファイル自体が暗黙的にstrictモードになるが、
// レガシーなスクリプトタグ環境を考慮し明示的な宣言を推奨する。

const UserProfileManager = (() => {
// 閉包(クロージャ)によってプライベートな状態をカプセル化
// 変数は必ず const または let で宣言し、暗黙のグローバル化をシャットアウトする
let _cachedUser = null;

/