0

我读过一本关于函数声明的书。代码是这样的。

function outer(){
    assert(typeof inner === "function", "inner() in scope before declaration");
    function inner(){}
    assert(typeof inner === "function", "inner() in scope after declaration");
    assert(typeof window.inner === "undefined", "inner() undefined in global space")
}

当测试运行时,所有三个语句都被断言为 true,表明 inner() 函数在其声明之前存在于范围内。我关于 javascript 的概念是脚本是逐行执行的,并且应该在调用之前声明函数。

问题是内部函数在声明之前如何存在于作用域中?

4

2 回答 2

1

我关于 javascript 的概念是脚本是逐行执行的,并且应该在调用之前声明函数。

这是不正确的。在 JavaScript 中,执行上下文中的所有函数声明都会在进入该执行上下文时进行处理,然后再执行任何分步代码。因此,函数内的函数声明在函数被调用时在进入函数时进行处理,并且在执行任何全局逐步代码之前处理全局范围的函数声明。这有时被称为“提升”(因为函数声明被有效地“提升”[提升]到它们声明的范围的顶部)。(旁注:var也被吊起,更多在我的博客上:可怜的被误解了var。)

这与函数表达式不同,函数表达式与所有表达式一样,在代码的逐步执行中进行评估。

这是一个函数声明:

function foo() { }

这里有三个函数表达式,请注意,在每种情况下,它们都用作右手值(例如,它们被分配给 var 或属性、传递给函数、在包含表达式中使用等),其中是什么让他们表达而不是声明:

var x = function foo() { };
obj = {
   b: function bar() { }
};
doSomethingWith(function() { });

在那里,我展示了两个命名函数表达式和一个匿名函数表达式。如果您要为 IE8 及更早版本编写代码,您可能希望避开命名函数表达式,因为 IE 的“JScript”解释器会出错;更多(也是我的博客):双重拍摄

于 2013-04-08T11:03:17.677 回答
0

Javascript 在两个 Pass 中执行一个函数,考虑一下:

有两种方法可以使用函数

1st: function quack(num){
      for(var i=0; i<num ; i++)
       {
        console.log("quacking")
       }
      } - this is a function declaration.   

2nd:   var fly = function(num){
        for(var i=0; i<num ; i++)
        {
         console.log("Flying!!!")
        }
       } - This is a function expression.

现在在第一遍中,javascript寻找函数声明
,它是

 function quack(num){
          for(var i=0; i<num ; i++)
           {
            console.log("quacking")
           }
          } 

因此,它将 quack 的引用分配给与该方法同名的变量,即.. quack。因此,如果您在声明它之前调用 quack(),它可以正常工作。

但是,在第二遍中,它会查找函数表达式,这
意味着您不能在评估它之前调用 fly。我希望这能给出更好的解释。

于 2018-01-03T08:51:26.003 回答