任何人都可以在另一个函数内解释这个函数的行为吗?

时间:2014-03-16 13:06:15

标签: javascript web lexical-scope

我试图理解Javascript中的词法范围。在下面的例子中,我在另一个函数中编写了一个函数。当我运行这个时,我希望在第一个警报中弹出“爸爸”,在第二个警报中弹出“妈妈”。但实际发生的是,它在第​​一个弹出窗口中显示“未定义”,在第二个弹出窗口显示“妈妈”。

function first(){
  var x = "dad"; 
  function second(){
    alert(x);
    var x = "mom";
    alert(x);
  }
  second();
}
first();

有人可以解释为什么在父函数中定义的变量“x”在子函数中不可见?奇怪的是,当我在子函数中删除变量“x”的声明时,它工作正常。有人可以在这里有效地了解词汇范围方案吗?

2 个答案:

答案 0 :(得分:5)

第二个var x'声明一个变量' x',它隐藏变量' x'在外部功能。任何对' x'的引用在第二个'函数是指该变量,即使它在声明之前。声明之前的变量值将是“未定义的”#。

你可以抬头'吊装'欲获得更多信息。请参阅:http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html

答案 1 :(得分:4)

您在x之后使用second语句在var中重新声明了alert。这使得xfirst中声明的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中,它是定义的。同时,xvar的值保持不变。

为了获得您期望的内容,并在两个函数中保持相同的second,您可以从function first(){ var x = "dad"; function second(){ alert(x); x = "mom"; alert(x); } second(); } first(); 中删除{{1}}声明并保留作业:

{{1}}