函数foo(){}和foo = function(){}之间的区别是什么?

可能重复:
JavaScript:var functionName = function(){} vs function functionName(){}

他们是一样的吗? 我一直在想


不,它们并不相同,尽管它们都会导致可以通过符号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)

请注意如何将是一个从单向函数声明能够正常工作(其中函数的名字加入到封闭范围)不同。

命名的函数表达式适用于兼容的实现,但过去在野外实现中存在一些错误,尤其是Internet Explorer 8和更早的版本(以及一些Safari的早期版本)。 IE8处理一个命名函数表达两次:首先作为函数声明(在进入执行上下文时),然后再作为函数表达式,在该进程中生成两个不同的函数。 (真。)

更多在这里:Double take和here:命名的函数表达式被揭秘


注:以下内容是在2011年编写的。2015年,控制块中的函数声明作为ECMAScript 2015的一部分添加到该语言中。它们的语义根据您处于严格还是松散模式以及松散模式(如果环境是一个网页浏览器。 当然,关于您使用的环境是否正确支持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的值。 现场示例。


我在提出非常类似的问题时得到了一个很好的解释:JavaScript中有两个同名的函数 - 这怎么能工作?

链接地址: http://www.djcxy.com/p/96299.html

上一篇: whats the difference between function foo(){} and foo = function(){}?

下一篇: var functionName = function() {} vs function functionName() {}