【问题标题】:Could anyone please explain this behavior of function inside another function?任何人都可以在另一个函数中解释函数的这种行为吗?
【发布时间】:2014-03-16 13:06:15
【问题描述】:

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

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

有人能解释一下为什么父函数中定义的变量“x”在子函数中不可见吗?奇怪的是,当我删除子函数中变量“x”的声明时,它工作正常。有人可以深入了解此处有效的词法作用域场景吗?

【问题讨论】:

    标签: javascript web lexical-scope


    【解决方案1】:

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

    您可以查找“吊装”以获取更多信息。见:http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html

    【讨论】:

    • @Darkhogg 提升是使词法作用域起作用的原因,一旦理解它就很漂亮,IMO。
    【解决方案2】:

    您通过在alert 之后使用var 语句在second 中重新声明了x。这使得xfirst 中声明的不同。

    此外,JavaScript 使用一种称为提升的技术。在作用域中声明变量时,该声明会在执行前传递期间移动到作用域的顶部。如果声明和赋值在一个语句中完成,则声明从赋值中分离出来。声明被移动到范围的顶部,导致一个未定义的变量,而赋值则留在原来的位置。

    pre-pass 后的结果代码如下所示(我这里只展示了变量的提升,只保留了函数)

    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();
    

    因此,在第一个alert 中,您的x 是新的且未定义的,而在第二个中它已定义。同时firstx的值保持不变。

    为了得到您所期望的,并在两个函数中保持相同的x,您将从second 中删除var 声明并保留分配:

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

    【讨论】:

      猜你喜欢
      • 2020-02-23
      • 2019-06-02
      • 2021-09-08
      • 2016-01-14
      • 1970-01-01
      • 1970-01-01
      • 2012-06-13
      • 1970-01-01
      • 2011-01-31
      相关资源
      最近更新 更多