JavaScript变量未定义vs未定义

JavaScript变量未定义vs未定义,javascript,variables,alert,variable-assignment,Javascript,Variables,Alert,Variable Assignment,我有一个附加了以下JavaScript的HTML页面 alert(box); box = "Thinking outside the box"; 在控制台中,我得到“未捕获引用错误:未定义框” 当我将其更改为: alert(box); var box = "Thinking outside the box"; 警报将被调用并显示未定义。我需要能够解释这一点,我对为什么会发生这种情况有一个模糊的概念。我知道当我使用var时,JavaScript在执行警报之前就知道变量在那里,但不一定给它赋值?

我有一个附加了以下JavaScript的HTML页面

alert(box);
box = "Thinking outside the box";
在控制台中,我得到“未捕获引用错误:未定义框”

当我将其更改为:

alert(box);
var box = "Thinking outside the box";

警报将被调用并显示未定义。我需要能够解释这一点,我对为什么会发生这种情况有一个模糊的概念。我知道当我使用var时,JavaScript在执行警报之前就知道变量在那里,但不一定给它赋值??我离这儿远吗?需要一些帮助来理解这一点。

当您使用
var
定义变量时,变量的声明被“提升”到作用域的顶部,从而为整个作用域定义变量。变量的初始化(分配其初始值)保持在代码中的相同位置

因此,在第二个示例中,当您执行
alert(box)
时,由于挂起的
var
语句,变量
box
已经声明。你的第二个例子:

alert(box);
var box = "Thinking outside the box";
基本上与此等效(将
变量的声明提升到范围的顶部):

这使得
box
变量在
alert(box)
语句之前声明(尽管未初始化),因此您得到的结果与所声明的变量一致,但还没有值(
alert()
报告
未定义
,这是变量存在但尚未初始化时发生的情况)

您的第一个示例没有使用
var
,因此在执行
alert(box)
的点上,根本没有名为
box
的变量,因此您得到了
未捕获的引用错误

这里有很多很多描述吊装细节的帖子。您可以在这里看到一个长长的列表:在这里您可以找到变量提升的进一步解释


注意:函数声明也被提升,因此您会发现一些帖子是关于函数声明而不是变量声明的,尽管概念基本相同。

这与变量提升有关。这意味着,变量声明(以及一般的声明)是在执行任何代码之前处理的,在代码中的任何位置声明变量等同于在顶部声明它。这也意味着变量可能在声明之前就被使用了

当您执行以下操作时:

alert(box)
var box = "Thinking outside the box"
这被含蓄地理解为:

var box;
alert(box);
box = "Thinking outside the box"
在第一种情况下,您没有变量声明,因此不会被提升,此时框是
未定义的

为什么会发生这种情况?

正如斯托扬·斯特凡诺夫(Stoyan Stefanov)在其著作《JavaScript模式》(JavaScript Patterns)中所解释的,提升是JavaScript解释器实现的结果:

为了完整性,让我们在实现时提到这一点 事情要复杂一点。这一过程分为两个阶段 代码处理,其中包含变量、函数声明和形式化 参数是在第一阶段创建的,这是 解析和输入上下文。在第二阶段,即 运行时代码执行、函数表达式和非限定 将创建标识符(未声明的变量)。但是为了实用 为了达到目的,我们可以采用起重的概念,但实际上并不是 由ECMAScript标准定义,但通常用于描述 行为

-Stoyan Stefanov,“JavaScript模式”


作为旁白,请阅读《安全牧羊人》的链接文章。

阅读关于“提升”呼叫框的内容,在您定义呼叫框之前,它并不存在,只有在您定义它时它才存在,无论“它”是否有值。您的理解基本上是这样的:)可能重复我会在3分钟内检查这个答案是否正确。哈哈,谢谢,我很感谢你的解释。我想我之所以很难找到另一个帖子,是因为我不懂这个词。现在我发现了很多问题。@EricB-是的,有时候你只需要知道最重要的搜索词。这是另一个很棒的答案,我想感谢你花时间在上面并参考了这本好书。我听说过Stoyan的JavaScript模式书,随着我对JavaScript了解的深入,这本书也在我的脑海中。谢谢你的回答,我已经将jfriend标记为正确的,但是我会给出你的答案,再次感谢你!
var box;
alert(box);
box = "Thinking outside the box"