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 控制台在沙箱中评估语句。

这是bugzilla 中关于它的一个公开错误

输入到 Web 控制台和 Scratchpad 的表达式在一个沙箱全局中进行评估,其原型是内容窗口:this.__proto__ === window

这有一些很好的效果:在 Scratchpad 中声明的变量实际上是该暂存器的本地变量,而不是污染内容的全局;你可以到处玩。如果确实想创建一个对内容可见的全局变量,总是可以简单地在窗口上创建一个属性:'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 回答