我有一个HTML页面,附带了以下JavaScript。
alert(box);
box = "Thinking outside the box";
在控制台中我得到" Uncaught ReferenceError:框未定义"
当我将其更改为:
alert(box);
var box = "Thinking outside the box";
警报被调用并显示未定义。我需要能够解释这一点,我对于为什么会发生这种情况有一个模糊的概念。我知道当我使用var时,JavaScript在执行警报之前知道变量是否存在,但是没有必要为它分配值?我离开这里了吗?需要一些帮助来理解这一点。
答案 0 :(得分:11)
当您使用var
定义变量时,变量的声明为"悬挂"到范围的顶部,因此变量是为整个范围定义的。变量的初始化(分配它的初始值)保留在代码中的相同位置。
因此,在您的第二个示例中,当您执行alert(box)
时,由于提升的box
语句,变量var
已经被声明。你的第二个例子:
alert(box);
var box = "Thinking outside the box";
基本上等同于此(box
变量的声明被提升到范围的顶部):
var box;
alert(box);
box = "Thinking outside the box";
这使box
变量在alert(box)
语句之前声明(虽然没有初始化),因此你得到的结果与声明的变量一致但是没有值({{ 1}}报告alert()
当变量存在但尚未初始化时会发生这种情况。
你的第一个例子没有使用undefined
因此没有提升,所以在你var
这一点上,没有任何名为alert(box)
的变量因此你得到了box
。
这里有很多很多帖子描述了吊装的细节。您可以在此处查看一长串列表:https://stackoverflow.com/search?q=javascript+variable+hoisting您可以在其中找到有关可变吊装的进一步说明。
注意:函数声明也会被提升,所以你找到的一些帖子将是关于函数声明而不是变量声明,尽管概念几乎相同。
答案 1 :(得分:2)
这与可变吊装有关。这意味着,在执行任何代码之前处理变量声明(以及一般的声明),在代码中的任何地方声明变量等同于在顶部声明它。这也意味着变量在声明之前似乎可以使用。
执行以下操作时:
alert(box)
var box = "Thinking outside the box"
这被隐含地理解为:
var box;
alert(box);
box = "Thinking outside the box"
在你的第一种情况下,你没有变量声明,因此没有悬挂,此时框是undefined
为什么会这样?
正如 Stoyan Stefanov 在他的书" JavaScript Patterns"中解释的那样,提升是JavaScript解释器实现的结果:
为了完整起见,我们实际上在实施时提到 水平的东西有点复杂。有两个阶段 代码处理,其中变量,函数声明和形式 参数是在第一阶段创建的,这是阶段 解析并输入上下文。在第二阶段,阶段 运行时代码执行,函数表达式和不合格 创建标识符(未声明的变量)。但实际上 目的,我们可以采用吊装的概念,实际上并非如此 由ECMAScript标准定义,但通常用于描述 行为。
- Stoyan Stefanov," JavaScript Patterns"
作为旁边阅读,请链接来自Safe Shepherd的this文章。