2013-03-19 30 views
2

在我試過的其他瀏覽器(例如Chromium,IE,Safari)中,在控制檯上執行的代碼的默認範圍(在任何函數之外)與在<script>中的函數外部執行的代碼的默認範圍相同。也就是說,this引用window對象,並且任何新聲明的變量都將成爲全局變量(以及等效的window對象的屬性)。Firefox Web控制檯的默認範圍 - 發生了什麼?

在Firefox ... 別的東西發生,但我不能弄清楚是什麼。在大多數瀏覽器中,this === window在Chrome控制檯中評估爲true,但在Firefox中它是錯誤的。儘管如此,Firefox的this.window === window也是如此。因此,通過控制檯新聲明或分配的變量不會對頁面上運行的腳本變得可見,除非您將它們顯式指定爲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 

背後發生了什麼? this在Firefox中引用的神祕對象是什麼,爲什麼它與window對象有這種特殊關係?這東西是否記錄在任何地方

(如果它的事項,我經歷過這種東西在Firefox 19.0.2。我沒有測試過其他版本的Firefox)

+0

聽起來像是在另一個範圍內運行。你看到的是原型繼承的工作原理。 (看起來好像你看到一個原型爲foo的對象)。 (相關問題我剛剛發現http://stackoverflow.com/questions/1803660/firebug-console-window-scope-why-isnt-this-always-the-same) – 2013-03-19 11:20:57

+0

嘗試在控制檯中運行'debugger;'。 – 2013-03-19 11:23:42

+0

我在我的手機上,所以我不能得到的鏈接,但谷歌「kangax刪除」,你應該得到這種奇怪的行爲的解釋。 – 2013-03-19 12:19:33

回答

3

什麼您遇到是因爲Firefox的Web控制檯評估在沙箱中陳述。 this.__proto__ === window

在Bugzilla中Here is an open bug about it進入Web控制檯和暫存器

表達式在沙箱中全球,其原型是內容窗口進行評估。

這有一些很好的效果:在Scratchpad中聲明的變量對於暫存器而言是有效的,而不是污染內容的全局;你可以玩。如果有人想要創建一個全局變量可見的內容,總是可以在窗口上創建一個屬性:'window.newGlobal =「fruit」'。

但是,我懷疑這實際上沒有幫助。開發人員最簡單的心智模式就是對Web Console/Scratchpad中輸入的代碼進行評估,就像其元素的內容一樣。解釋爲什麼'x'顯示內容的x但'x = 5'不會改變它(但'xy = 5'對內容可見!)涉及一定程度的細節,只有更多的參與開發者纔有興趣。

提供內容中不存在的實用函數當然是有價值的;但是可以通過評估應用於具有效用函數作爲其屬性的對象的'with'表達式的表達式來完成。 '與'並不是我最喜歡的構造,但是由於我們完全控制了對象的屬性,'一般'使用的缺點並不適用;一旦你決定引入一些Web控制檯功能,'with'的行爲幾乎就是你所需要的。(不要忘了,下面對全球產生的X和Y的綁定:

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

所以「與」不重新引入沙盤問題我在上面提到)

關於這是如何工作的。在JavaScript中,繼承是典型的。沙箱是一個對象,其原型是窗口,而不是窗口本身。 MDN中的Here is a tutorial about it

+0

甜 - 不僅你在網上追蹤了我曾經失敗過的一些關於這個問題的討論,但它是有益的,有趣的討論,解釋了行爲。謝謝。 – 2013-03-19 11:51:06

+0

非常歡迎。我只想提到這個問題在螢火蟲中不存在。隨意瀏覽我關於原型鏈的其他答案 – 2013-03-19 11:51:50