89

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

たとえば、次の4つのファイルについて考えてみます。

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

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

これが可能かどうか、またはこれを達成するための回避策があるかどうか誰かに教えてもらえますか?

4

5 に答える 5

92

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

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"
于 2009-06-03T12:09:01.437 に答える
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 やその他のツールを使用して、より信頼性が高く、ハッキングの少ないランタイム環境の検出を行うこともできると思います。

于 2014-04-06T11:37:49.263 に答える