Javascript 命名函数表达式和使用变量引用之间的差异?

Javascript 命名函数表达式和使用变量引用之间的差异?,javascript,function,closures,scopes,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 = make

从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() {
  alert( shooter.i )
}
shooter.i = i

换句话说,为什么第一个能像预期的那样工作,而第二个不能?第一个(给函数本身一个名称并从函数内部使用它)和第二个(使用引用函数的变量)之间的实际区别是什么?

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

否则,它将在运行时定义

在其初始值设定项表达式(
function(){…}
)完成之前,不能引用变量
shooter
。如果你说

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

它可以正常工作,因为变量已经声明,并且在函数表达式求值点的作用域中。

只是补充Steve所说的内容。当提到函数声明时,您会听到术语“highed”

在本例中,何时声明函数并不一定重要,因为在解析脚本时,它会首先遍历并查找所有函数声明

i、 e

在执行函数表达式时,只能在赋值后使用函数,因为函数是JavaScript中的值

i.e.
alert(fnDeclaration());
var fnDeclaration = function() {
    return "It won't work :(";
}
这是二者区别的一般要点

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