命名函数表达式与使用变量引用之间的区别?

时间:2013-03-31 11:34:35

标签: javascript function closures scopes

来自javascript.info:

function makeArmy() {

  var shooters = []

  for(var i=0; i<10; i++) {

    var shooter = function shoot() {
      alert( shoot.i )
    }
    shooter.i = i

    shooters.push(shooter)   
  }

  return shooters
}

var army = makeArmy()

army[0]() // 0
army[1]() // 1

有趣的部分:

var shooter = function shoot() {
  alert( shoot.i )
}
shooter.i = i

我的问题是:为什么以下不起作用:

var shooter = function() {
  alert( shooter.i )
}
shooter.i = i

换句话说,为什么第一个按预期工作,而第二个没有?第一个(赋予函数本身名称并在函数内使用它)和第二个(使用引用函数的变量)之间的实际差异是什么?

3 个答案:

答案 0 :(得分:2)

当函数具有名称(声明)时,它在解析时定义。它变得全球化。

否则它是在运行时定义的。

http://markdaggett.com/blog/2013/02/15/functions-explained/

答案 1 :(得分:1)

在初始化表达式(shooter)完成之前,您无法引用变量 function() {...}。如果相反,你说

var shooter;
shooter = function() { alert(shooter.i); }

它可以正常工作,因为变量已经被声明,并且在范围内被评估函数表达式。

答案 2 :(得分:0)

只是补充史蒂夫说的话。在引用函数声明时,您会听到“提升”一词。

在这个例子中,声明函数时并不一定重要,因为解析脚本时它首先会通过并查找所有函数声明。

alert(fnDeclaration());
function fnDeclaration() {
    return "It works!";
}

在执行函数表达式的情况下,只能在分配函数后使用该函数,因为函数是JavaScript中的值。

i.e.
alert(fnDeclaration());
var fnDeclaration = function() {
    return "It won't work :(";
}

这是两者之间差异的一般要点。