一个关于Javascript函数的简单问题,调用/定义的差异

一个关于Javascript函数的简单问题,调用/定义的差异,javascript,Javascript,有人能解释一下以下函数定义之间的区别吗 var alertMessage = function alertMessage(message) { alert(message); } var alertMessage = function(message) { alert(message); } 每种方法的含义是什么?谢谢 两者都是函数表达式,基本上区别在于第一个是命名的,第二个是匿名的 例如: var test = function test(message) { alert(me

有人能解释一下以下函数定义之间的区别吗

var alertMessage = function alertMessage(message) {
  alert(message);
}

var alertMessage = function(message) {
  alert(message);
}
每种方法的含义是什么?谢谢

两者都是函数表达式,基本上区别在于第一个是命名的,第二个是匿名的

例如:

var test = function test(message) {
  alert(message);
};

var test1 = function(message) {
  alert(message);
};

test.name; // "test"
test1.name // "" or "anonymous"
注意:函数对象的
name
属性在某些实现中存在,但它是非标准的

此外,函数表达式的名称对于调试也很有用,因为您可以检查调用堆栈以查看您的位置

此标识符只能从
函数体
本身内部访问:

(function foo(){
  typeof foo; // "function"
})();
typeof foo; // "undefined"

但是,JScript实现(在IE的所有版本中)上都有一个定义,该名称泄漏到其封闭范围。

这两个定义都是函数表达式,而不是函数声明或由
函数
构造函数创建的函数。它们都为变量
alertMessage
分配了一个函数。区别在于第一个函数是命名的,而第二个函数是匿名的

命名函数通常用于函数声明中,例如

function alertMessage(message) { ... }
在这种情况下,函数声明将在当前范围内创建一个名为
alertMessage
的变量,该变量引用该函数。函数声明被提升到当前作用域的顶部,因此您可以在
js
文件中定义声明的函数之前调用它们

函数表达式(如原始问题)中使用的命名函数不会创建此变量,也不会被提升到执行范围的顶部,因此按照惯例,大多数函数表达式都是匿名的。命名函数表达式的唯一好处是
name
变量绑定在函数内(尽管CMS提到,这取决于实现),函数名从函数的
toString
方法输出。这在调试期间非常有用(而不是让Firebug输出
(?)
用于大量匿名函数调用)


相关分析中有更详细的内容:(特别是“命名函数表达式”一节)阅读此答案,我认为您会找到所需的任何信息:错误比这更糟糕,它还确保函数被创建两次,一次在封闭范围开始时,一次在赋值时。如果为变量指定了不同的名称,则同一函数将有两个不相等的副本(如果要将类与
instanceof
!)进行比较,则可能会导致问题)。最好:避免使用命名的内联函数表达式。是的@bobince这种行为太糟糕了,对我来说,它变成了一条简单的“不要那样做”规则,这太可惜了,因为它太有用了。Erlang没有办法做到这一点(基本上是一个“letrec”),这是一个真正的痛苦。@bobnice,@Pointy:是的,我认为这是ECMA标准最可怕的偏差之一,你们知道吗,这个错误仍然存在于IE9平台预览中?!!,标识符泄漏到其封闭范围,但似乎只创建了一个函数实例…:-(谢谢大家,这帮了大忙!