0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【JavaScript】グローバルスコープ/モジュールスコープの違い

Last updated at Posted at 2025-02-10

JavaScript におけるグローバルスコープとモジュールスコープの違い

JavaScript では、関数や変数を グローバルスコープ で定義するか、モジュールスコープ に限定するかによって、挙動が大きく異なります。特に、ブラウザ環境で HTML のインラインイベント (onclick="executeFunction()") で関数を呼び出す場合、グローバルスコープが関係するため注意が必要 です。


1. window.executeFunction = function() { ... }; (グローバルスコープ)

window.executeFunction = function() {
    console.log("関数が実行されました");
};

📌 グローバルスコープの特徴

window はブラウザのグローバルオブジェクトwindow に代入すると、どこからでも executeFunction() を呼び出せる。
HTML のインライン onclick="executeFunction()" でも呼び出し可能
他のスクリプトやモジュールからもアクセス可能 だが、名前の衝突リスク がある。

HTML のインラインイベントが動作する例

<button onclick="executeFunction()">関数を実行</button>

➡️ インライン onclickexecuteFunction() を実行可能window.executeFunction として登録されているため)。


2. var executeFunction = function() { ... }; (古い書き方)

var executeFunction = function() {
    console.log("関数が実行されました");
};

📌 var の特徴

var で宣言した変数は関数スコープを持つ
ブラウザのグローバルスコープでは window.executeFunction に近い挙動をするが、ES Modules では異なる挙動をとる
var は再宣言が可能なため、意図しない変数の上書きが発生しやすい
ES6 以降は var は推奨されず、constlet が主流

var の問題点

  • グローバルスコープを汚染しやすい
  • letconst のようにブロックスコープを持たない

推奨される書き方

let executeFunction = function() {
    console.log("関数が実行されました");
};

3. const executeFunction = function() { ... }; (モジュール / ブロックスコープ)

const executeFunction = function() {
    console.log("関数が実行されました");
};

📌 モジュールスコープの特徴

constlet で定義した変数はスコープ内でのみ有効
モジュール (type="module") や {} の中で定義すると、グローバルには公開されない
HTML のインライン onclick="executeFunction()" ではエラーになる(グローバルスコープに登録されないため)。

HTML のインラインイベントが動作しない例

<button onclick="executeFunction()">関数を実行</button>

➡️ Uncaught ReferenceError: executeFunction is not defined となる。

代わりに addEventListener を使うべき

document.getElementById("actionButton").addEventListener("click", executeFunction);

4. type="module" を指定した場合の違い

JavaScript の <script> タグに type="module" を指定すると、そのスクリプトはデフォルトでモジュールスコープとなり、グローバルオブジェクト (window) に変数や関数を登録しなくなる という重要な違いがあります。

📌 type="module" の特徴

モジュール内の変数や関数はグローバルスコープに登録されない
import / export を使用してスクリプトを分割できる
ブラウザ環境でも strict mode が自動適用される

HTML のインライン onclick="executeFunction()" は動作しない

<script type="module">
    const executeFunction = () => {
        console.log("関数が実行されました");
    };
</script>

<button onclick="executeFunction()">関数を実行</button>

➡️ エラー (executeFunction is not defined)

解決策: window に登録する

<script type="module">
    window.executeFunction = () => {
        console.log("関数が実行されました");
    };
</script>

<button onclick="executeFunction()">関数を実行</button>

➡️ このように window.executeFunction = ... とすることで、グローバルに公開可能

または addEventListener を使用する

<script type="module">
    document.getElementById("actionButton").addEventListener("click", () => {
        console.log("関数が実行されました");
    });
</script>

<button id="actionButton">関数を実行</button>

➡️ グローバルを汚さず、スコープを適切に管理できる!


5. どの書き方を選ぶべきか?

書き方 スコープ インライン onclick で呼べる? 推奨度
window.executeFunction = ... グローバルスコープ ✅ 呼べる ⚠️ (小規模なら OK, 乱用注意)
var executeFunction = ... 関数スコープ ✅ 呼べる ❌ 非推奨
const executeFunction = ...let executeFunction = ... モジュール / ブロックスコープ ❌ 呼べない ✅ 推奨
type="module" を使用 モジュールスコープ ❌ 呼べない ✅ 推奨 (ES Modules 用)

小規模 & 手軽にインラインイベントを使いたいwindow.executeFunction に登録
大規模 & 保守性重視addEventListener を使い、スコープを適切に管理
モジュール分割が必要なら type="module" を活用


結論: 「グローバルに公開すべきか?」を考えて適切なスコープ設計を! 🚀

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?