2012-11-16 11 views
5

私はES6で自分をドラフト探してみましたが、私は見てどこか分からない:`ECMAScriptの中にグローバルスコープのthis` 6

ES6でthisは必ずしもグローバルを参照している場合、誰かが私に言うことができますオブジェクト?また、このオブジェクトはグローバルスコープと同じメンバを持つでしょうか?

もしあなたがES5のために答えることができればそれも役に立つでしょう。

グローバルスコープ内のthisは、ブラウザやその他のほとんどのES環境(ノードなど)のグローバルオブジェクトを指しています。私はそれが仕様によって定義された振る舞いか、それが実装者が追加した拡張動作(そしてこの振る舞いがES6の実装で継続するかどうか)であるかどうかを知りたいだけです。さらに、グローバルオブジェクトは常にグローバルスコープと同じですか?または区別がありますか?


アップデート - なぜ私が知りたい:私は基本的に確実にES5 &それがブラウザに固有のだから、私はwindowに頼ることはできません6.でグローバルオブジェクトを取得する方法を把握しようとしています、 globalに依存することもできません。これは、ノードなどの環境に固有のものであるためです。私はNode内のがモジュールスコープのmoduleを参照できることを知っていますが、それでもグローバルスコープのglobalを参照していると思います。グローバルオブジェクト(可能な場合)を取得するには、クロス環境ES5 & 6準拠の方法が必要です。グローバルスコープのthisが知っているすべての環境のようですが、実際の仕様の一部であるかどうかを知りたいと思います。

また、グローバルスコープとグローバルオブジェクトが仕様によって同じものかどうかを知る必要があります。つまり、グローバルスコープ内のすべての変数はglobalobject.variable_nameと同じになりますか?


アップデート2 - 私は何をしようとしている:

私はいくつかのES6 shims for ES5 environmentsを開発しました。 (1)シムの代わりに可能なときに使用できるようにES6ビルトインがすでに存在するかどうかを確認し、(2)シムをグローバルスコープに追加するには、既に存在していません。

現在、私はこのパターンを次のようだ:

(function() { 

    // Indirect eval to run in global scope. 
    // (We get whatever "this" is in global scope, hoping that it's the global object... 
    // Whether this line does what I want it to is the crux of my question.) 
    var global = (0, eval)('this'); 

    // If Symbol does not already exist in global scope, 
    if (!global.Symbol) 

     // Then add Symbol to global scope. 
     global.Symbol = (function() { 

      // ... 
      // Return my Symbol shim 

     })(); 

})(); 

あり(1)のためのいくつかの他の可能性がありますが、一日の終わりに私はvarを使用せずにグローバルスコープに何かを追加する方法が必要ですグローバルスコープ(これは、少なくとも私が間接的にevalvarステートメントも間接的に可能性がありますか?))のために、私はそれらをチェックする前に内蔵型をオーバーライドするので、varホイストすることができます。私は自分のコードを厳密なモードで実行できるようにして、コンパウンドが問題になるようにします。

私は、ES5仕様では、間接的なevalがグローバルスコープでコードを実行することを発見しました。だから私は少なくともそれを行うことができます。私の質問は、グローバルスコープでを取得した場合です。(1)そのオブジェクトのプロパティをチェックすると、ビルトインがすでにグローバルスコープに存在するかどうかがわかりますか? (2)そのオブジェクトにプロパティを追加すると、グローバルスコープに変数を追加できますか?

+3

「this」はES6固有ではないため、以前のES仕様と同様に動作するはずです。 'this'の意味は、それがどこで使われているかによって異なり、常にグローバルオブジェクトではありません。 – Jay

+0

。だから、私は "グローバルスコープ"に尋ねました。ブラウザでは、 "this"はグローバルオブジェクトでもある 'window'と同じです。しかし、これがESで指定されているのか、それともその言語のブラウザ拡張機能なのかは分かりません。 –

+1

あなたがSESのようなものにいない限り、間接的なevalトリックは確実に機能します。グローバルオブジェクトがあればそれに割り当ててプロパティをチェックすることができます。これにより、必要な処理が実行されます。 es6では、let、constなどについてAndreasが言ったことを超えて、主要なグローバルオブジェクトを外部スコープとする独自のプライベートグローバルを持つモジュールの問題もあるため、直接参照がない限り外部グローバルにアクセスしたり変更することは不可能です(例えば 'global'を自動的に定義するnode.jsのように、あなたはその外側のグローバルへの参照を与えます)。 –

答えて

2

はい、グローバルスコープのthisは、引き続きES6のグローバルオブジェクトを参照します。 (一般的に、ES6は完全に下位互換性がある、すなわちES5で動作することが保証されたコードはES6でも動作するはずです)。

しかし、 "グローバルスコープ"という概念は、もはやES6のグローバルオブジェクトと同一ではありません。字句的にスコープが変更された新しい宣言フォームが導入されています(letconstclassmoduleなど)。前回の会合での結論は、これらのどれもグローバルオブジェクトのプロパティとして現れないということでした。そのための技術的および方法論的な理由は多岐にわたりますが、最終的にはグローバルオブジェクトを直接使用することを避けることが最善です(これは常に真ですが、ES6ではさらにそうです)。

グローバルオブジェクトが必要な特定のものがありますか?

+0

あなたの専門知識を提供していただきありがとうございます!私はなぜあなたが私の元の投稿の**アップデート2 **でグローバルオブジェクトをしたいのかという質問に答えました。あなたは見て、私が従うパターンが良いものかどうかを見てみることができますか?ありがとうございました! –

0

ほとんどはい。この動作は、(理解し、下位互換性の問題のために)ES6に滞在することを意図している

(function(global){ /* do stuff! */ }(this)); 

:任意の非オブジェクト(またはthis非設定)でthisを渡す

はグローバルオブジェクトを参照します。そしてそれが私が知っているマルチプラットフォーム(ブラウザ/ノード)プラグインの大部分がグローバルオブジェクトにアクセスする方法です。例:https://github.com/documentcloud/underscore/blob/master/underscore.js#L12

サーバ上のプラグインがmodule(エクスポートされている)としてthisにしかアクセスしていないことは確かです。しかし、それはあなたがノードで欲しいものです。あなたのグローバルスペースは決してクリーンアップされません(手動で行った場合、またはサーバーを再起動した場合を除く)。したがって、すべてのクライアント接続で共有されます。グローバルな空間に何かを割り当てることは、本当に良い考えではありません。それはエラーがスローされますthisではJavaScriptが「バージョン」の間でどのように扱われるかの唯一の顕著な違いがstrict modeである


nullまたはundefinedがの位置にcallまたはapplyまたはbind(に渡された場合でありますthis value)。非厳密モードでは、thisはグローバルオブジェクトに強制されました。

"use strict"; 
foo.apply(null); // Throw error 

このヘルプが必要です。

+2

フレーズで不明瞭になっているかもしれませんが、 'foo.apply(null);'はstrictモードでエラーを投げません。 '関数foo(){this.doSomething(); } 'は' this'がない場合(例えば、 'this'が' null'または 'undefined')、厳密なモードでエラーをスローします。それはあなたが言ったことかもしれませんが、後世のためにもっと明確に書いておきたいかもしれません。 –

関連する問題