我见过其他人使用以下模式。
var bar = function foo(){};
console.log(bar); // foo()
console.log(foo); // ReferenceError: foo is not defined
但为什么呢?如果两者都被宣布,我可以看到这一点,但事实并非如此。原因是什么?
答案 0 :(得分:7)
调试应用程序时,使用“命名”匿名函数时,更容易知道调用堆栈中调用的是什么。因此,这是一种为匿名函数命名以进行调试的方法。
试试这个并查看调试器中的callstack:
myDiv = document.getElementById("myDiv");
myDiv.onclick = function OnClick(){
debugger;
//do something
}
答案 1 :(得分:7)
正如其他人所提到的,使用示例中的第一个表单(命名函数表达式)可以帮助调试,尽管最近浏览器中内置开发人员工具的改进,这个论点是变得不那么有说服力了。使用命名函数表达式的另一个原因是,您可以将函数名称用作函数体内的变量,而不是ES5 arguments.callee
中现在弃用的函数。
但是,命名函数表达式错误且在Internet Explorer中实现有问题< 9,当您定位这些浏览器时,通常应该避免使用。有关详细信息,请参阅Juriy Zaytsev's excellent article on the subject。
答案 2 :(得分:2)
他们正在命名一个匿名函数,因为它使调试更容易。在调试时,您将在调用堆栈中看到对“foo”的调用,而不是对“匿名”的一堆调用。
答案 3 :(得分:2)
我能想象到的唯一原因是为函数提供所需的名称。这有助于调试,因为检查器使用函数对象的name
属性。试试这个:
var bar = function foo(){};
console.log(bar.name); // foo
如果你在foo中放入一些真正的代码并在浏览器中为JavaScript调试器添加一个断点,你会在调用堆栈中看到该函数为foo
。
答案 4 :(得分:0)
函数定义(或文字)有4个部分。 1.保留字function
2.可选名称,调试器或函数可以使用它来递归调用自身。 3.参数和4.由{ }
在函数范围之外,foo不存在。但是,由于您已将该函数分配给变量栏,因此可以使用方法调用栏来调用它,并且由于定义了栏,因此可以打印它。
如果您对JavaScript感兴趣,请务必考虑获取Douglas Crockford's book Javascript: The Good Parts