【テクニカル・上級編】 厳格モード(use strict)と変数宣言 – JavaScript実践ガイド

現代のJSエンジニアが「use strict」を軽視してはいけない理由 —— グローバル汚染と暗黙の破壊からコードを守る

フロントエンドの戦場において、コードの堅牢性は「書く」ことではなく「書かせない」仕組みによって担保されます。

多くの若手エンジニアが `const` や `let` に移行し、モダンなビルド環境に甘んじている今、あえて問いましょう。「なぜ、今さら `use strict` なのか?」と。結論から言えば、それは単なるレガシーな作法ではありません。JavaScriptエンジンがコードを最適化し、メモリのリークを防ぎ、予期せぬ実行時エラーを未然に叩き潰すための「最初の防衛線」だからです。

1. 意図しない「グローバル変数の生成」という名の時限爆弾

`use strict` がない世界では、JavaScriptは驚くほど寛容です。宣言していない変数に値を代入しようとした瞬間、エンジンは文句を言わずにグローバルオブジェクト(ブラウザなら `window`)にそのプロパティを生やしてしまいます。

// ‘use strict’ を指定しない場合
function initializeApp() {
// 打ち間違いで ‘config’ が ‘confg’ になっていたら?
confg = { theme: ‘dark’ };
// ここで window.confg が生成される。
// TypeScriptを使用していても、any型経由で発生すると検知不能なバグになる。
}

これは単なるバグではありません。アプリケーションが肥大化した際、「誰がどのタイミングでグローバル空間を汚染したのか」を突き止めるのは、メモリリークのデバッグよりも過酷な作業です。`use strict` は、この「暗黙のグローバル化」を即座に `ReferenceError` として通知してくれます。これが、堅牢なアーキテクチャの第一歩です。

2. 巻き上げ(Hoisting)とTDZの境界線

`var` は、関数スコープという「広すぎる」スコープと、宣言の巻き上げという「直感的でない」挙動のために、現代のアーキテクチャでは戦力外です。`let` や `const` を使うことで、変数は「一時的なデッドゾーン(TDZ)」に守られます。

しかし、もしあなたがレガシーなライブラリをラップしたり、動的にスクリプトを注入するような高度なアーキテクチャを組む場合、`use strict` がなければ `var` や `function` 宣言の巻き上げによる「変数の上書き」に気づくことすらできません。

‘use strict’;

function runTask() {
console.log(processStatus); // TDZによりReferenceErrorになる。varならundefinedになる。
let processStatus = ‘ready’;
}

この「初期化前にアクセスしたら即座に死ぬ」という挙動こそ、パフォーマンス最適化の観点からも重要です。不完全な状態で処理を進めるより、早い段階でクラッシュさせるほうが、デバッグコストは圧倒的に低いのです。

3. エンジンによる最適化への貢献

ブラウザのV8エンジンなどのJIT(Just-In-Time)コンパイラは、コードが厳格であるほど最適化をかけやすくなります。

`use strict` 下では、`this` の挙動が明確化されます。非厳格モードでは `this` が `undefined` の場合に自動的にグローバルオブジェクトに束縛されますが、厳格モードでは `undefined` のままです。この「不確定要素の排除」は、エンジンがインラインキャッシュ(Inline Cache)を効率的に利用し、メモリ消費を抑え、実行速度を向上させるためのヒントとなります。

4. 実戦的な設計指針:モジュール化による自動適用

現代のフロントエンド開発において、`use strict` を個別に記述する必要はほとんどありません。なぜなら、ES Modules(`import` / `export`)を導入した時点で、JavaScriptは自動的に厳格モードで動作するからです。

もし、レガシーなScriptタグで読み込んでいるコードがあるなら、即座にIIFE(即時実行関数)で囲み、そのトップに宣言を配置してください。

(function() {
‘use strict’;

// このスコープ内は厳格モードで保護される
const appConfig = Object.freeze({ API_KEY: ‘secret’ });

// 読み取り専用プロパティへの代入を試みると、
// 厳格モードでは明確な TypeError を投げてくれる
appConfig.API_KEY = ‘hacked’;
})();

結論:コードは「防御的」であるべきだ

優れたアーキテクトは、自分のコードを信用しません。人間は必ずミスをするし、ライブラリのアップデートで挙動が変わることもあります。

`use strict` は、そうしたヒューマンエラーやエンジンの気まぐれを封じ込め、アプリケーションを常に「クリーンな状態」に保つための規約です。もしあなたが、まだ「なんとなく動いている」コードに不安を感じているなら、まずはそのファイルの一行目に `’use strict’;` を刻むことから始めてください。

その一行が、将来のあなたを数え切れない深夜のデバッグから救うことになります。技術とは、常にそうした「泥臭い防衛」の積み重ねの上にしか存在しないのです。

コメント

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