2013-03-19 32 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