可能重复:
JavaScript:var functionName = function(){} vs function functionName(){} }
它们是一样的吗?我一直很好奇
可能重复:
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)
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中同名的两个函数是如何工作的?
let
的函数表达式。 - T.J. Crowder