21

不明なホスト環境でES5strictモードでグローバルオブジェクトへのハンドルを取得するための推奨される方法は何ですか?

ECMAScriptは、私が知っているグローバルオブジェクトを参照するための組み込みの方法を提供していません。もしそうなら、これは私が探している答えです。

既知の環境では、グローバルオブジェクトは通常自己参照プロパティを持っています。グローバルオブジェクトはグローバルスコープのVOであるため、グローバルオブジェクトのプロパティはグローバル変数であり、どこからでもグローバルオブジェクトへのハンドルを取得するために使用できます。

  • Webブラウザーでは、windowまたはを使用できますself

  • node.jsでは、を使用できますglobal

ただし、これは必ずしもすべてのホスト環境に当てはまるわけではありません。私の知る限り、WindowsScriptHostはグローバルオブジェクトにアクセスする方法を提供していません。WSHでグローバルオブジェクトを取得するための推奨される方法はthis、オブジェクトに解決されないコンテキストでキーワードを使用することです。例えば:

var GLOBAL = (function(){return this}());

この手法は、どのホスト環境でも機能しますが、strictモードでは機能しません。これは、undefinedがstrictモードthisでグローバルオブジェクトを参照しないためです。

これが厳密なモードコード内で評価される場合、この値はオブジェクトに強制変換されません。nullまたは未定義のこの値はグローバルオブジェクトに変換されず、プリミティブ値はラッパーオブジェクトに変換されません。関数呼び出し(Function.prototype.applyおよびFunction.prototype.callを使用して行われた呼び出しを含む)を介して渡されたこの値は、渡されたこの値をオブジェクト(10.4.3、11.1.1、15.3.4.3、15.3)に強制しません。 4.4)。

予想どおり、次のコードは次のようになりますundefined

(function(){
    "use strict";
    var GLOBAL = (function(){return this}());
    console.log(GLOBAL);
}());

では、 strictモードに関係なく、任意の環境でグローバルオブジェクトへのハンドルを取得する適切な方法は何ですか?

ちなみに、私の現在のアプローチは、次のようにグローバルオブジェクトを参照するグローバル変数をスニッフィングすることです。

var self, window, global = global || window || self;

...そして使用するだけglobalです。これは多くの理由で悪い解決策だと思いますが、そのほとんどはかなり明白であり、WSHの問題に対処していません。

4

4 に答える 4

29

ES5では、間接評価呼び出しを介して、厳密モード内からグローバルオブジェクトへの参照を取得できます。

"use strict";
var global = (1,eval)('this');

私の記事を見てください; 特にストリクトモードのこのセクションで

于 2012-03-10T14:42:03.577 に答える
7

グローバルコードでは、thisBindingstrictモードに関係なく、はグローバルオブジェクトに設定されます。つまり、そこからモジュールIEFEに渡すことができます。

// "use strict"; or not
(function(global) {
    "use strict";
    …
    console.log(global);
    …
}(this));
于 2013-06-04T00:03:12.897 に答える
1

厳密モードでは、グローバルオブジェクトへの参照を取得する方法は、それ自体を参照するグローバルオブジェクトに変数を割り当てることです。

これはthis、グローバルコンテキストにある場合のグローバルオブジェクトを意味するため、解決策は次のようになります。

"use strict";
var global = global || this;
(function() { global.hello = "world"; })();
console.log(hello); // Outputs 'world' as expected

これ、グローバル名前空間をそれ自体への参照で汚染する必要があることを意味しますが、あなたが言うように、それはすでにそこにあるはずです。

于 2012-03-10T00:47:10.243 に答える
0

Mathias Bynensは、このテーマに関する優れた記事を掲載しています。use strict以下は、Chrome拡張機能など、CSPが有効になっている環境を含め、すべての環境で機能するか、機能しません。

(function() {

    // A globalThis polyfill | # | Adapted from https://mathiasbynens.be/notes/globalthis

    if (typeof window !== 'undefined' && window && window.window === window) { return window } // all browsers
    else { // webworkers, or server-side Javascript, like Node.js
        try {
            Object.defineProperty( Object.prototype, '__magic__', { // hocus pocus
                get: function() {
                    return this;
                },
                configurable: true // This makes it possible to 'delete' the getter later
            });
            __magic__.globalThis = __magic__;
            delete Object.prototype.__magic__;

            return globalThis;
        } catch (e) {
            // we shouldn't ever get here, since all server-side JS environments that I know of support Object.defineProperty
            return (typeof globalThis === 'object') ? globalThis : ( (typeof global === 'object') ? global : this );
        }
    }
})();
于 2020-11-11T05:21:03.177 に答える