2022年7月1日

グローバルオブジェクト

グローバルオブジェクトは、どこからでも利用できる変数と関数を提供します。デフォルトでは、言語または環境に組み込まれているものです。

ブラウザではwindow、Node.js では global、他の環境では別の名前になる場合があります。

最近、globalThis がグローバルオブジェクトの標準化された名前として言語に追加され、すべての環境でサポートされるようになりました。主要なブラウザすべてでサポートされています。

ここでは、環境がブラウザであることを前提としてwindowを使用します。スクリプトが他の環境で実行される可能性がある場合は、代わりに globalThis を使用する方が良いでしょう。

グローバルオブジェクトのすべてのプロパティは直接アクセスできます。

alert("Hello");
// is the same as
window.alert("Hello");

ブラウザでは、varlet/const ではありません!)で宣言されたグローバル関数と変数は、グローバルオブジェクトのプロパティになります。

var gVar = 5;

alert(window.gVar); // 5 (became a property of the global object)

関数宣言も同じ効果があります(メインコードフローでのfunctionキーワードによる文であり、関数式ではありません)。

それに依存しないでください!この動作は互換性のために存在します。最近のスクリプトでは、このようなことが起こらないJavaScriptモジュールを使用しています。

代わりにletを使用した場合、このようなことは起こりません。

let gLet = 5;

alert(window.gLet); // undefined (doesn't become a property of the global object)

グローバルに利用できるようにしたいほど重要な値である場合は、プロパティとして直接書き込みます。

// make current user information global, to let all scripts access it
window.currentUser = {
  name: "John"
};

// somewhere else in code
alert(currentUser.name);  // John

// or, if we have a local variable with the name "currentUser"
// get it from window explicitly (safe!)
alert(window.currentUser.name); // John

とはいえ、グローバル変数の使用は一般的に推奨されていません。グローバル変数は可能な限り少なくする必要があります。関数が「入力」変数を受け取り、特定の「結果」を生成するコード設計は、外部またはグローバル変数を使用する場合よりも明確で、エラーが発生しにくく、テストが容易になります。

ポリフィルの使用

グローバルオブジェクトを使用して、最新の言語機能のサポートをテストします。

たとえば、組み込みのPromiseオブジェクトが存在するかどうかをテストします(非常に古いブラウザには存在しません)。

if (!window.Promise) {
  alert("Your browser is really old!");
}

(たとえば、古いブラウザにいる場合)存在しない場合は、「ポリフィル」を作成できます。つまり、環境でサポートされていないが、最新の標準には存在する関数を追加します。

if (!window.Promise) {
  window.Promise = ... // custom implementation of the modern language feature
}

概要

  • グローバルオブジェクトは、どこでも利用できる必要がある変数を保持します。

    これには、ArrayのようなJavaScript組み込みや、ブラウザのウィンドウの高さであるwindow.innerHeightのような環境固有の値が含まれます。

  • グローバルオブジェクトには、普遍的な名前globalThisがあります。

    …しかし、より頻繁には、window(ブラウザ)やglobal(Node.js)のような「昔ながらの」環境固有の名前で参照されます。

  • 値は、プロジェクトにとって真にグローバルな場合にのみグローバルオブジェクトに格納する必要があります。そして、その数を最小限に抑えてください。

  • ブラウザでは、モジュールを使用していない限り、varで宣言されたグローバル関数と変数は、グローバルオブジェクトのプロパティになります。

  • コードを将来にわたって有効にし、理解しやすくするためには、window.xのように、グローバルオブジェクトのプロパティに直接アクセスする必要があります。

チュートリアルマップ

コメント

コメントする前にこれを読んでください…
  • 改善すべき点について提案がある場合は、コメントする代わりにGitHub issueを提出するか、プルリクエストをしてください。
  • 記事の内容が理解できない場合は、詳しく説明してください。
  • コードを数語挿入するには、<code>タグを使用し、数行の場合は<pre>タグで囲み、10行を超える場合はサンドボックス(plnkrjsbincodepen…)を使用してください。