はじめに
先日から、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の場合などの挙動は確認していません。
おわりに
以上、レガシー環境にも配慮したグローバルオブジェクトへのアクセス方法でした。
次は何を書こうかしら・・・