はじめに
先日から、JavaScriptのグローバルオブジェクトについて記事を書いてきました。
記事を書くたびにコメントから学びがあり、ありがたい限りです。
今回もコメントいただいたthisとFunction('return this')()について
this / Function('return this')() のメリット
最初に、今回紹介するものを使うメリットを示します。
基本的にはglobalThisで良さそうなのですが、globalThisは比較的新しい機能のようで、レガシー(古い)環境では対応していない可能性が考えられます。
その点、this / Function('return this')() はより古くから使用されているため、レガシーな環境を想定するならこちらを使うと良いようです。
それでは、それぞれについて見ていきましょう。
this
グローバルコンテキストにおいて、thisはグローバルオブジェクトを指します。
// In web browsers, the window object is also the global object: console.log(this === window); // true this.b = "MDN"; console.log(window.b); // "MDN" console.log(b); // "MDN"
this === globalThis === window(ブラウザの場合)ですね。
this はコンテキストを意識して使用する globalThis とも言えます。
Function('return this')()
グローバルコンテキスト以外においては、Function('return this')()を使ってグローバルコンテキストを取得できるようです。
分解して理解してみましょう。
Function()
よく使う関数宣言 function() との違いは、f が大文字であることです。
Functionコンストラクターは、新しいFunctionオブジェクトを生成します。
新しい関数を生成しているようです。
Functionコンストラクターはグローバルスコープで実行される関数のみを生成します。
つまり、この中でthisはグローバルオブジェクトを指すようです。
Function() の使い方
構文は以下です。
new Function([arg1 [, arg2 [, ...argN]] ,] functionBody)
例
const sum = new Function('a', 'b', 'return a + b'); console.log(sum(2, 6)); // Expected output: 8
つまり、Function('return this')は、以下の関数を生成していたわけですね。
function() {
return this; // thisはグローバルオブジェクト
}
そして、関数の実行には () が必要です。console.log() , sum() などなど・・・
そのため、ここでも () を最後につけて、Function('return this')() となったわけですね。
globalThis との併用
ここまで見てきたやり方で、レガシーな環境に配慮する場合に this / Function('return this')() を使うことができるようになりました。
しかし、globalThisとは違い、コンテキストを意識したコーディングが必要になり、不便・可読性が落ちる・バグの温床 という問題が生まれます。
そこで、以下のコードをグローバルに仕込み、globalThisを使うと良いようです。
<script>
if (!this.globalThis) this.globalThis = Function('return this')();
</script>
※レガシー環境の再現方法がわからず、strict modeの場合などの挙動は確認していません。
おわりに
以上、レガシー環境にも配慮したグローバルオブジェクトへのアクセス方法でした。
次は何を書こうかしら・・・