在我尝试的其他浏览器中(例如Chromium,IE,Safari),在控制台(在任何函数之外)执行的默认代码范围与在{{中的函数外部执行的代码的代码相同。 1}}。也就是说,<script>
引用this
对象,任何新声明的变量都成为全局变量(等同于window
对象的属性)。
在Firefox中...... 其他东西会发生,但我无法弄清楚是什么。在大多数浏览器中,window
评估为Chrome控制台中的this === window
,但在Firefox中则为假。不过,true
在Firefox中也是如此。因此,除非您明确地将它们指定为this.window === window
对象的属性,否则通过控制台新声明或分配的变量对页面上运行的脚本不可见。
怪癖并不止于此。对window
对象进行的分配会在Firefox控制台的范围内神奇地传播和修改变量,但反之则不然。例如:
window
幕后发生了什么? 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
对象有这种奇特的关系?这些东西记录在哪里吗?
(如果重要的话,我在Firefox 19.0.2中体验过这些东西。我还没有测试过其他Firefox版本。)
答案 0 :(得分:3)
您遇到的是因为Firefox Web控制台评估沙箱中的语句。
在bugzilla中在Web控制台中输入的表达式和Scratchpad在全局沙箱中进行评估,其原型是内容窗口:
this.__proto__ === window
。这有一些很好的效果:在Scratchpad中声明的变量实际上是该暂存器的本地变量,而不是污染内容的全局;你可以玩。如果确实想创建一个对内容可见的全局变量,可以在窗口上创建一个属性:'window.newGlobal =“fruit”'。
但是,我怀疑这实际上没有用。开发人员最简单的心理模型是在Web控制台/ Scratchpad中输入的代码,就像元素的内容一样进行评估。解释为什么'x'显示内容的x但'x = 5'不会改变它(但'xy = 5' 对内容可见!)涉及一定程度的细节,只有更多参与的开发人员对。有兴趣。
提供内容中不存在的实用功能当然很有价值;但这可以通过使用实用程序函数作为其属性来评估应用于对象的'with'表达式范围内的表达式来完成。 'With'不是我最喜欢的构造,但由于我们完全控制了对象的属性,因此一般使用'with'的缺点不适用;一旦你决定引入一些仅限Web控制台的功能,'with'的行为就是你所需要的。 (不要忘记以下内容在全局上为x和y创建绑定:
with (o) { var x = 5; y = 6; }
所以'with'不会重新引入我上面提到的沙盒问题。)
关于这是如何运作的。在JavaScript中,继承是典型的。沙箱是一个对象,其原型是窗口而不是窗口本身。 MDN Here is a tutorial about it。