我见过其他人使用以下模式。
var bar = function foo(){};
console.log(bar); // foo()
console.log(foo); // ReferenceError: foo is not defined
但为什么?如果两者都被声明,我可以看出这一点,但他们没有。原因是什么?
我见过其他人使用以下模式。
var bar = function foo(){};
console.log(bar); // foo()
console.log(foo); // ReferenceError: foo is not defined
但为什么?如果两者都被声明,我可以看出这一点,但他们没有。原因是什么?
正如其他人所提到的,在您的示例中使用第一种形式(命名函数表达式)可以帮助调试,尽管随着浏览器中内置开发人员工具的最近改进,这个论点变得不那么有说服力了。使用命名函数表达式的另一个原因是您可以将函数名称用作函数体内的变量,而不是 ES5 中现已弃用的变量arguments.callee。
但是,在 Internet Explorer < 9 中,命名函数表达式的实现不正确且有问题,当您针对这些浏览器时,通常应避免使用。有关更多信息,请参阅Juriy Zaytsev 关于该主题的优秀文章。
在调试应用程序时,当使用“命名”匿名函数时,更容易了解调用堆栈中的调用内容。因此,这是一种为调试目的为匿名函数命名的方法。
试试这个并在调试器中查看调用堆栈:
myDiv = document.getElementById("myDiv");
myDiv.onclick = function OnClick(){
debugger;
//do something
}
他们命名一个匿名函数是因为它使调试更容易。调试时,您将在调用堆栈中看到对“foo”的调用,而不是对“匿名”的一堆调用。
我能想到的唯一原因是给函数一个想要的名字。这有助于调试,因为检查器使用函数对象的name属性。试试这个:
var bar = function foo(){};
console.log(bar.name); // foo
如果您在 foo 中放入一些实际代码并在浏览器中的 JavaScript 调试器中添加断点,您将foo在调用堆栈中看到该函数。
函数定义(或文字)有 4 个部分。1. 保留字function2. 可供调试器或函数递归调用自身的可选名称。3. 参数和 4. 被包裹的函数体{ }
在函数范围之外, foo 不存在。但是由于您将函数分配给变量 bar,您可以使用方法调用 bar 调用它,并且由于定义了 bar,您可以打印它。
如果你对 JavaScript 感兴趣,你真的应该考虑阅读Douglas Crockford 的书 Javascript: The Good Parts