2

私が試した他のブラウザ (Chromium、IE、Safari など) では、コンソールで実行されるコードのデフォルトのスコープ (関数の外側) は、<script>. つまり、はオブジェクトthisを参照し、window新しく宣言された変数はすべてグローバル (および、同等にwindowオブジェクトのプロパティ) になります。

Firefox では...何か他のことが起こりますが、何が原因かわかりません。ほとんどのブラウザーでは、Chrome コンソールでthis === window評価されますtrueが、Firefox では false です。this.window === windowただし、Firefox では当てはまります。windowこのため、コンソールを介して新しく宣言または割り当てられた変数は、オブジェクトの属性として明示的に割り当てない限り、ページ上で実行されているスクリプトには表示されません。

奇抜さはそれだけにとどまりません。オブジェクトへの割り当ては、window魔法のように Firefox コンソールのスコープ内の変数を伝播して変更しますが、その逆は当てはまりません。例:

window.foo = 5;
console.log(foo); // 5
console.log(this.foo); // 5
console.log(window.foo); // 5
foo = 10;
console.log(foo); // 10
console.log(this.foo); // 10
console.log(window.foo); // 5 -- in any other browser, this would be 10

舞台裏で何が起こっているのですか?Firefox で参照されている謎のオブジェクトとは何ですか?thisまた、オブジェクトとこの奇妙な関係があるのはなぜwindowですか? これはどこかに文書化されていますか?

(念のため、私は Firefox 19.0.2 でこのようなことを経験しました。他の Firefox バージョンはテストしていません。)

4

1 に答える 1

3

あなたが経験しているのは、Firefox Web コンソールがサンドボックス内のステートメントを評価するためです。

これについては、バグジラで未解決のバグがあります

Web コンソールとスクラッチパッドに入力された式は、プロトタイプがコンテンツ ウィンドウであるサンドボックス グローバルで評価されますthis.__proto__ === window

これにはいくつかの良い効果があります。スクラッチパッドで宣言された変数は、コンテンツのグローバルを汚染するのではなく、事実上そのスクラッチパッドに対してローカルです。あなたは遊ぶことができます。コンテンツから見えるグローバル変数を作成したい場合は、いつでも window にプロパティを作成できます: 'window.newGlobal = "fruit"'.

しかし、これは実際には役に立たないと思います。開発者にとって最も単純なメンタル モデルは、Web コンソール/スクラッチパッドに入力されたコードが、要素のコンテンツと同じように評価されることです。「x」はコンテンツの x を示し、「x = 5」はそれを変更しない (ただし、「xy = 5」コンテンツに表示される!) 理由の説明には、より熱心な開発者だけが関心を持つ程度の詳細が含まれます。

コンテンツにはないユーティリティ機能を提供することは確かに価値があります。しかし、これは、ユーティリティ関数をプロパティとして持つオブジェクトに適用された 'with' 式のスコープ内で式を評価することによって実行できます。「With」は私の好みの構文ではありませんが、オブジェクトのプロパティを完全に制御するため、「with」を使用する一般的な欠点は当てはまりません。いくつかの Web コンソールのみの機能を導入することに決めたら、'with' の動作はほとんど必要なものです。(以下は x と y のバインディングをグローバルに作成することを忘れないでください:

with (o) { var x = 5; y = 6; }

したがって、'with' は、私が上で言及したサンドボックスの問題を再導入するものではありません。)

これがどのように機能するかについて。JavaScript の継承はプロトタイプです。サンドボックスとは、プロトタイプがウィンドウであり、ウィンドウ自体ではないオブジェクトです。これについてのチュートリアルが MDN にあります。

于 2013-03-19T11:48:56.373 に答える