在函数内部使用var关键字声明变量为什么在幕后未定义

问题描述

我是新手,我想确保我正确理解var的吊装。

var a = 2;
var x = function() {
   console.log(a);
   var a = 1;
};
x();

调用“ x”函数时,得到的答案是“未定义”; 因此,引擎会看到在“ x”的功能范围内有一个变量“ a”并将其分配给“ undefined”;

如果我们在函数内取出变量“ a”:

var a = 2;
var x = function() {
   console.log(a);
}
x();

然后我们得到答案“ 2”,因为引擎在函数“ x”内查找是否存在变量“ a”,因为在这里找不到它,因此它在外部/父/全局范围内查找并找到变量“ a”。

我没事吗?

解决方法

是的,您完全正确。当您说以下内容时,请注意以下几点:

因此,引擎看到在“ x”的功能范围内有一个变量“ a”并将其分配给“ undefined”;

它更像是:仅悬挂声明,而不初始化。并且已声明但未初始化的变量默认为undefined。参见https://www.w3schools.com/js/js_hoisting.asp#midcontentadcontainer

对于第二个函数,是的,这是正确的:首先,它在函数的作用域内查找,然后,由于找不到它,因此在父作用域内,然后在父对象的父对象内,依此类推。

,

简而言之,当您这样做时:

var a = 2;
function() {
   console.log(a);
   var a = 1;
}

JavaScript在解释您的代码之前先“吊起”您的变量声明,基本上将您的代码转换为此:

var a = 2;
function() {
   // there a now new "a" variable which is undefined
   var a; 
   console.log(a);
   a = 1;
}

当JS解析变量时,它会爬升函数范围,直到找到与所需变量匹配的变量。悬挂内部的“ a”变量时,它实际上将覆盖外部的“ a”变量。过去,优良作法是将所有变量声明为“ up top”,以防止出现任何奇怪的意外问题。 constlet不存在提升问题-这就是为什么今天的大多数代码都是使用这些代码而不是var编写的。