モジュールスコープとは
ES Modules では、各モジュールファイルが独自のスコープを持ちます。これを「モジュールスコープ」と呼びます。従来のスクリプトとは異なり、変数がグローバルを汚染することがありません。
グローバルスコープとの違い
通常のスクリプトでは、トップレベルで宣言した変数はグローバルスコープに追加されます。
<!-- 通常のスクリプト -->
<script src="a.js"></script>
<script src="b.js"></script>// a.js
var name = "Alice";
let count = 0;// b.js
console.log(name); // "Alice"(グローバルに見える)
console.log(count); // エラーまたは意図しない動作モジュールスコープの動作
モジュールでは、各ファイルが独立したスコープを持ちます。
<!-- モジュールとして読み込み -->
<script type="module" src="a.js"></script>
<script type="module" src="b.js"></script>// a.js
const name = "Alice";
let count = 0;
// name と count は a.js 内でのみ有効// b.js
console.log(name); // ReferenceError: name is not defined
console.log(count); // ReferenceError: count is not defined通常のスクリプト
トップレベルの変数はグローバル(window)に追加される。名前の衝突が起きやすい。
ES Modules
各ファイルが独立したスコープを持つ。明示的に export/import しない限り、他のモジュールからアクセスできない。
エクスポートによる公開
他のモジュールで使いたい値は、明示的にエクスポートする必要があります。
// a.js
export const name = "Alice";
const secret = "hidden"; // エクスポートしないのでプライベート// b.js
import { name } from './a.js';
console.log(name); // "Alice"
console.log(secret); // エラー(アクセスできない)this の違い
モジュールのトップレベルでは、this は undefined になります。
// 通常のスクリプト
console.log(this === window); // true
// モジュール
console.log(this); // undefinedグローバルへのアクセス
モジュール内からグローバルオブジェクトにアクセスしたい場合は、明示的に window(ブラウザ)や globalThis を使用します。
// モジュール内でグローバルを設定
globalThis.myApp = {
version: "1.0.0"
};
// または
window.myApp = {
version: "1.0.0"
};globalThis
ES2020 で導入された、環境を問わずグローバルオブジェクトにアクセスできる標準的な方法です。
window
ブラウザ環境でのみ使用可能です。Node.js では使えません。
モジュールスコープの利点
// module.js
// これらはモジュール外からはアクセスできない
const privateData = [];
let counter = 0;
function privateHelper() {
// 内部的なヘルパー関数
}
// 公開したいものだけエクスポート
export function addItem(item) {
privateData.push(item);
counter++;
}
export function getCount() {
return counter;
}モジュールスコープにより、カプセル化が自然に実現され、保守性の高いコードを書くことができます。