web-dev-qa-db-ja.com

.jsファイルでグローバル変数を宣言する方法

すべての.jsファイルに必要ないくつかのグローバル変数が必要です。

たとえば、次の4つのファイルを考えます。

  1. global.js
  2. js1.js
  3. js2.js
  4. js3.js

global.jsで3つのグローバル変数を宣言し、他の3つの.jsファイルでそれらにアクセスして、上記の4つのファイルをすべてHTMLドキュメントにロードすることを考慮した方法はありますか?

誰かがこれが可能かどうか、またはこれを達成するための回避策がありますか教えてください。

82
kp11

関数スコープの外側のglobal.jsで変数を定義するだけです:

// global.js
var global1 = "I'm a global!";
var global2 = "So am I!";

// other js-file
function testGlobal () {
    alert(global1);
}

これが機能することを確認するには、そのファイルで定義されている変数にアクセスする前に、global.jsをインクルード/リンクする必要があります。

<html>
    <head>
        <!-- Include global.js first -->
        <script src="/YOUR_PATH/global.js" type="text/javascript"></script>
        <!-- Now we can reference variables, objects, functions etc. 
             defined in global.js -->
        <script src="/YOUR_PATH/otherJsFile.js" type="text/javascript"></script>
    </head>
    [...]
</html>

もちろん、js-filesのロードで初期ページのロードを中断させたくない場合は、終了<body>-タグの直前にスクリプトタグをリンクできます。

90

推奨されるアプローチは次のとおりです。

window.greeting = "Hello World!"

その後、任意の関数内でアクセスできます。

function foo() {

   alert(greeting); // Hello World!
   alert(window["greeting"]); // Hello World!
   alert(window.greeting); // Hello World! (recommended)

}

このアプローチは、2つの理由で好まれます。

  1. 意図は明示的です。 varキーワードを使用すると、ローカルまたはその逆を目的としたグローバルvarsを簡単に宣言できます。この種の変数スコープは、多くのJavascript開発者にとって混乱のポイントです。したがって、一般的なルールとして、すべての変数宣言の前にキーワードvarまたはプレフィックスwindowを必ず付けます。

  2. このように変数を読み取るためにこの構文を標準化します。つまり、ローカルスコープのvarはグローバルvarを上書きしません。たとえば、ここで何が起こるかはあいまいです:

 greeting = "Aloha";

 function foo() {
     greeting = "Hello"; // overrides global!
 }

 function bar(greeting) {
   alert(greeting);
 }

 foo();
 bar("Howdy"); // does it alert "Hello" or "Howdy" ?

ただし、これははるかにクリーンでエラーが発生しにくくなります(変数スコープ規則をすべて覚える必要はありません)。

 function foo() {
     window.greeting = "Hello";
 }

 function bar(greeting) {
   alert(greeting);
 }

 foo();
 bar("Howdy"); // alerts "Howdy"
85
aleemb

試しましたか?

もしあなたがそうするなら:

var HI = 'Hello World';

global.jsで。それから:

alert(HI);

js1.jsでは、正常に警告されます。 HTMLドキュメントの残りの前にglobal.jsを含める必要があります。

唯一の問題は、ウィンドウのスコープで宣言する必要があることです(関数内ではなく)。

var部分を削除して、そのように作成することもできますが、それは良い習慣ではありません。

7

上記のように、スクリプトファイルの最上位スコープの使用には問題があります。別の問題があります。スクリプトファイルは、一部のランタイム環境でグローバルコンテキストではないコンテキストから実行される可能性があります。

グローバルをwindowに直接割り当てることが提案されています。しかし、それは実行時依存であり、Nodeなどでは機能しません。ポータブルなグローバル変数管理のニーズを示しています慎重な検討と追加の努力。多分彼らは将来のECMSバージョンでそれを修正するでしょう!

今のところ、すべてのランタイム環境で適切なグローバル管理をサポートするには、次のようなものをお勧めします。

/**
 * Exports the given object into the global context.
 */
var exportGlobal = function(name, object) {
    if (typeof(global) !== "undefined")  {
        // Node.js
        global[name] = object;
    }
    else if (typeof(window) !== "undefined") {
        // JS with GUI (usually browser)
        window[name] = object;
    }
    else {
        throw new Error("Unkown run-time environment. Currently only browsers and Node.js are supported.");
    }
};


// export exportGlobal itself
exportGlobal("exportGlobal", exportGlobal);

// create a new global namespace
exportGlobal("someothernamespace", {});

入力はもう少し多くなりますが、グローバル変数管理が将来にわたって保証されます。

免責事項: stacktrace.js の以前のバージョンを見ると、このアイデアの一部が思い浮かびました。

また、Webpackまたは他のツールを使用して、ランタイム環境の検出の信頼性を高め、ハッキングを軽減することもできます。

5
Domi

はい、それらにアクセスできます。次のように(関数の外で) 'パブリックスペース'で宣言する必要があります。

var globalvar1 = 'value';

後で、他のファイルでもアクセスできます。

2
Ropstah