这个JavaScript片段是怎么回事

Whats going on with this JavaScript snippet?

本文关键字:怎么回事 片段 JavaScript 这个      更新时间:2023-09-26

From http://dmitry.baranovskiy.com/post/91403200

if (!("a" in window)) {
    var a = 1;
}
alert(a);

以下是我得到的结果:

  • 铬控制台 - [对象对象]
  • 萤火虫 - 未定义
  • 野生动物园控制台 - 未定义
  • 杰斯菲德尔 - 1

这是怎么回事??!我预计未定义,因为"if"应该返回一个假(因为窗口中的"a"应该是假的,而 !false 应该是真的,因此变量 a 永远不会得到一个值)。我错过了什么?

编辑:好的,我意识到var语句首先执行,窗口中的"a"仅返回此类变量是否存在。但是,为什么Firebug和jsfiddle给出了不同的答案呢?

这段代码被javascript解释器看到如下:

var a;
if (!("a" in window)) {
    a = 1;
}
alert(a);

根据a是否已存在于全局作用域中以及代码是在全局作用域中运行还是在本地作用域中运行,此代码有四种排列。

如果代码在本地函数作用域中运行,则它基本上如下所示:

function whatever() {
    var a;
    if (!("a" in window)) {
        a = 1;
    }
    alert(a);
}

因此,以下是排列:

global a exists already      scope code runs in       value of alert(a)
-----------------------------------------------------------------------
yes, has value of 2          global                   2
yes exists, value undefined  global                   undefined
no                           global                   1
yes, has value of 2          local                    undefined
yes exists, value undefined  local                    undefined
no                           local                    1

因此,您获得的答案之所以不同,是因为在每种情况下,此代码运行的范围都不同。

在jsFiddle中,您必须小心左上角的设置。 如果设置为 onload ,则 jsFiddle 在本地函数作用域(onload 处理程序函数)中运行。

这里发生的事情是,如果此代码正在运行全局范围,则("a" in window)将始终为真,因为代码的var a部分被提升在执行代码上方,因此全局范围内var a始终被执行,因此始终存在("a" in window)。 因此,在全局范围内运行时,a = 1永远不会执行,alert(a)只是输出全局a值的任何值。 如果它以前有一个定义的值,那就是您将看到的。 如果它以前没有定义的值,那么它只会提醒undefined因为(认为它存在)它没有被分配值。

如果此代码在本地范围内运行,则alert(a)将始终在alert(a)中看到本地定义的a。 因此,如果没有全局a,您将看到1值,因为这样a = 1将在本地a上执行。 或者,如果存在全局a,则a = 1将永远不会执行,因此本地定义的a将始终undefined,这就是警报将显示的内容。