T.J*_*der 31
不,它们不一样,虽然它们都会产生一个可以通过符号调用的功能foo.一个是函数声明,另一个是函数表达式.它们在不同的时间进行评估,对它们的定义范围产生不同的影响,并且在不同的地方是合法的.
在这里引用我对这个问题的答案(编辑了一点相关性),以防其他问题由于某种原因被删除(以及保存链接后的人):
JavaScript有两个不同但相关的东西:函数声明和函数表达式.它们之间有明显的差异:
这是一个函数声明:
function foo() {
    // ...
}
在执行任何分步代码之前,在进入封闭范围时评估函数声明.函数的名称(foo)被添加到封闭范围(从技术上讲,函数的定义的执行上下文的变量对象).
这是一个函数表达式(具体来说,是一个匿名函数,就像你引用的代码一样):
var foo = function() {
    // ...
};
函数表达式作为逐步代码的一部分进行评估,在它们出现的位置(就像任何其他表达式一样).那个创建一个没有名称的函数,它分配给foo变量.
函数表达式也可以命名而不是匿名.一个命名的看起来像这样:
var x = function foo() {  // Valid, but don't do it; see details below 
    // ...
};
根据规范,命名函数表达式应该是有效的.它应该创建一个具有名称的函数foo,但不要放在foo封闭范围内,然后将该函数分配给x变量(当在逐步代码中遇到表达式时,所有这些都会发生).当我说它不应该放在foo封闭的范围内时,我的意思是:
var x = function foo() {
    alert(typeof foo); // alerts "function" (in compliant implementations)
};
alert(typeof foo);     // alerts "undefined" (in compliant implementations)
请注意这与函数声明的工作方式有何不同(函数名称被添加到封闭范围中).
命名函数表达式适用于兼容的实现,但在野外实现中曾经有过几个bug,尤其是Internet Explorer 8及更早版本(以及Safari的早期版本).IE8处理命名函数表达式两次:首先作为函数声明(在进入执行上下文时),然后作为函数表达式,在进程中生成两个不同的函数.(真.)
更多信息:Double take and here:命名函数表达式揭秘
注意:下面是2011年编写的.2015年,控制块中的函数声明作为ECMAScript 2015的一部分添加到语言中.它们的语义根据您是处于严格模式还是松散模式而变化,如果环境模式处于松散模式是一个Web浏览器.当然,关于您使用的环境是否正确支持ES2015的定义.(令我惊讶的是,截至2017年7月的写作,Babel也没有正确地将它们转换为.)因此,在特定情况下,你只能在控制流结构中可靠地使用函数声明,所以它现在仍然是最好的,改为使用函数表达式.
最后,他们之间的另一个区别是他们是合法的.函数表达式可以出现在表达式可以出现的任何地方(几乎在任何地方).函数声明只能出现在其封闭范围的顶层,在任何控制流语句之外.例如,这是有效的:
function bar(x) {
    var foo;
    if (x) {
        foo = function() {  // Function expression...
            // Do X
        };
    }
    else {
        foo = function() {  // ...and therefore legal
            // Do Y
        };
    }
    foo();
}
...但这不是,并且不会像大多数实现那样做:
function bar(x) {
    if (x) {
        function foo() {  // Function declaration -- INVALID
            // Do X
        }
    }
    else {
        function foo() {  // INVALID
            // Do Y
        }
    }
    foo();
}
它非常有意义:由于foo函数声明在进入函数时被评估bar,因此在执行任何逐步代码之前,解释器不知道foo要评估哪个.这对表达式来说不是问题,因为它们是在控制流程中完成的.
由于语法无效,实现可以自由地执行他们想要的操作.我从来没有遇到过一个能达到预期效果的,就是抛出语法错误而失败.相反,几乎所有这些都忽略了控制流语句,并且如果foo在顶层有两个函数声明(它使用第二个;在规范中),它们应该做它们应该做的事情.所以只使用第二个foo.Firefox的SpiderMonkey是杰出的,它似乎(有效地)将它们转换为表达式,因此它使用取决于它的值x.实例.
| 归档时间: | 
 | 
| 查看次数: | 14058 次 | 
| 最近记录: |