我试图理解Javascript中的词法范围。在下面的例子中,我在另一个函数中编写了一个函数。当我运行这个时,我希望在第一个警报中弹出“爸爸”,在第二个警报中弹出“妈妈”。但实际发生的是,它在第一个弹出窗口中显示“未定义”,在第二个弹出窗口显示“妈妈”。
function first(){
var x = "dad";
function second(){
alert(x);
var x = "mom";
alert(x);
}
second();
}
first();
有人可以解释为什么在父函数中定义的变量“x”在子函数中不可见?奇怪的是,当我在子函数中删除变量“x”的声明时,它工作正常。有人可以在这里有效地了解词汇范围方案吗?
答案 0 :(得分:5)
第二个var x
'声明一个变量' x',它隐藏变量' x'在外部功能。任何对' x'的引用在第二个'函数是指该变量,即使它在声明之前。声明之前的变量值将是“未定义的”#。
你可以抬头'吊装'欲获得更多信息。请参阅:http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html
答案 1 :(得分:4)
您在x
之后使用second
语句在var
中重新声明了alert
。这使得x
与first
中声明的function first(){
var x;
x = "dad";
function second(){
var x; //new variable in local scope, declared not defined
alert(x); //alerts undefined
x = "mom"; //defines local `x` as "mom"
alert(x); //alerts "mom"
}
second();
}
first();
不同。
此外,JavaScript使用称为提升的技术。当在作用域中声明变量时,该声明将在执行前传递期间移动到作用域的顶部。如果声明和转让是在一个声明中完成的,则声明将脱离该声明。声明被移动到范围的顶部,导致未定义的变量,而分配留在原始位置。
预传后的结果代码如下所示(我只在这里展示了变量的提升并且单独留下了函数)
alert
因此,在第一个x
中,x
是新的且未定义的,而在第二个first
中,它是定义的。同时,x
中var
的值保持不变。
为了获得您期望的内容,并在两个函数中保持相同的second
,您可以从function first(){
var x = "dad";
function second(){
alert(x);
x = "mom";
alert(x);
}
second();
}
first();
中删除{{1}}声明并保留作业:
{{1}}