INDEX
グローバル名前空間の回避とは?

JavaScriptでは、グローバルスコープで宣言された変数や関数はグローバル名前空間に登録され、ページ内の他のスクリプトからもアクセスできるようになります。
小規模なプログラムでは問題になりにくいものの、複数のJavaScriptファイルやライブラリを利用する大規模な開発では、同じ名前の変数や関数が存在してしまい、予期しない上書きやバグの原因になることがあります。
現在では、ES6モジュールを利用してコードをモジュール化し、グローバル名前空間を汚染しない設計が推奨されています。
グローバル名前空間の問題点
グローバルスコープに変数や関数を定義すると、他のスクリプトと名前が重複する可能性があります。
グローバル名前空間の問題の例
// script1.js
var counter = 10;
console.log(counter);
// 10
// script2.js
var counter = 20;
console.log(counter);
// 20
// script1.jsのcounterが上書きされる
この例では、両方のファイルで同じ名前の変数を宣言しているため、後から読み込まれたスクリプトによって値が上書きされてしまいます。
script1.jsでcounterが作成されます。script2.jsでも同じ名前の変数を宣言しています。- 後から読み込まれた変数で上書きされるため、意図しない動作になる可能性があります。
ES6モジュールによるグローバル名前空間の回避
ES6モジュールでは、各ファイルが独立したモジュールスコープを持ちます。そのため、モジュール内で宣言した変数や関数は、exportしない限り外部からアクセスできません。
ES6モジュールを使った例
// counter.js
let counter = 0;
export function increment() {
counter++;
return counter;
}
// main.js
import { increment } from "./counter.js";
console.log(increment());
// 1
console.log(increment());
// 2
この例では、counterはcounter.jsの内部だけで管理されます。外部から直接アクセスできないため、他のJavaScriptファイルと名前が衝突することはありません。
モジュール化のメリット
モジュール化すると、単に名前の衝突を防ぐだけではなく、コード全体の保守性も向上します。
| メリット | 説明 |
|---|---|
| グローバル名前空間を汚さない | モジュール内の変数や関数は外部へ漏れない。 |
| 名前の衝突を防げる | 同じ変数名でも別々のモジュールで安全に利用できる。 |
| 再利用しやすい | 必要な機能だけをexportして他のファイルで利用できる。 |
| 保守しやすい | 役割ごとにファイルを分割でき、見通しが良くなる。 |
現在推奨される書き方
現在のJavaScriptでは、グローバル変数をできるだけ作らないことが推奨されています。
- 変数は
constやletで宣言する。 - 複数ファイルで管理する場合はES6モジュールを利用する。
- 必要な機能だけを
exportする。 - 利用する側では
importして使用する。
なお、letやconstをグローバルスコープで宣言しても、スクリプト全体から利用できるため、名前の衝突自体は防げません。根本的な対策としてはモジュール化が最も有効です。
初心者がつまずきやすいポイント
varだけでなく、グローバルなletやconstも名前の衝突の原因になる。- モジュール内で宣言した変数は、自動では外部から利用できない。
- 外部で利用したいものだけを
exportする。 - 利用する側では
importが必要になる。 - 現在のJavaScriptでは、ES6モジュールを利用した設計が一般的である。
まとめ
- グローバル名前空間にはすべてのスクリプトからアクセスできる変数や関数が登録される。
- グローバル変数が増えると名前の衝突や予期しない上書きが発生しやすくなる。
- ES6モジュールを利用すると、各ファイルが独立したスコープを持つ。
exportとimportを利用することで必要な機能だけを共有できる。- 現在のJavaScriptでは、モジュール化によってグローバル名前空間を避ける設計が推奨されている。