1. ホーム
  2. javascript

[解決済み] JavaScriptでグローバルオブジェクトを取得する方法は?

2023-07-06 17:33:58

質問

あるスクリプトで、他のモジュールがすでにロードされているかどうかをチェックしたい。

if (ModuleName) {
    // extend this module
}

しかし、もし ModuleName が存在しない場合、その throw s.

が分かっていれば Global Object がわかれば、それを使うことができるのに。

if (window.ModuleName) {
    // extend this module
}

しかし、私は自分のモジュールを両方のブラウザで動作させたいので node , rhino などと仮定することはできません。 window .

私の理解では、これはES 5では動作しません。 "use strict" ;

var MyGLOBAL = (function () {return this;}()); // MyGlobal becomes null

これも例外が投げられて失敗します

var MyGLOBAL = window || GLOBAL

ということで、残っているのは

try {
    // Extend ModuleName
} 
catch(ignore) {
}

これらのケースはいずれもJSLintを通過しません。

何か見逃していませんか?

どのように解決するのですか?

さて、あなたは typeof 演算子を使用すると、識別子がスコープチェーンのどの場所にも存在しない場合、その識別子は ではなく を投げます。 ReferenceError を返します。 "undefined" :

if (typeof ModuleName != 'undefined') {
  //...
}

また this の値は、グローバルオブジェクトを参照します。 if ステートメントがグローバルコンテキストにある場合、単純に this.ModuleName .

について (function () { return this; }()); のテクニックについてですが、おっしゃるとおり、ストリクトモードでは this の値は単に undefined .

ストリクトモードでは、どこにいてもグローバルオブジェクトへの参照を取得する方法が2つあります。

  • を通して Function のコンストラクタを使用します。

    var global = Function('return this')();
    
    

で作成された関数は Function コンストラクタで作成された関数は、呼び出し元の厳密性を継承せず、ボディを 'use strict' ディレクティブで始まる場合のみストリクトで、それ以外は非ストリクトです。

このメソッドは、あらゆるES3実装と互換性があります。

  • を通して 間接的 eval コール といった具合です。

    "use strict";
    var get = eval;
    var global = get("this");
    
    

上記が動作するのは、ES5では、間接的な呼び出しを eval への間接的な呼び出しは グローバル環境 をevalコードの変数環境と語彙環境の両方として使用します。

の詳細を参照してください。 評価コードの入力 をご覧ください。

しかし、最後の解決策はES3実装では動作しないことに注意してください。 eval への間接的な呼び出しは、呼び出し元の変数と語彙環境をevalコード自体の環境として使用するからです。

そして最後に、ストリクトモードがサポートされているかどうかを検出するのに便利なことがあります。

var isStrictSupported = (function () { "use strict"; return !this; })();