2012-03-12 57 views
15

我见过其他人使用以下模式。为什么JavaScript函数声明(和表达式)?

var bar = function foo(){}; 
console.log(bar); // foo() 
console.log(foo); // ReferenceError: foo is not defined 

但是为什么?如果两者都被宣布,我可以看到这一点,但他们不是。为什么是这个原因?

+3

你有什么就有什么,有一个名称的匿名函数。我知道这样做的唯一原因是当你调试到foo()函数时,堆栈跟踪将显示名称而不是“匿名函数”。 – 2012-03-12 12:47:03

回答

7

正如其他人所提到的,使用第一种形式在您的示例(命名函数表达式)与调试帮助,但在内置的浏览器开发者工具,这种说法变得不那么有说服力的最新改进。使用命名函数表达式的另一个原因是,您可以使用函数名称作为函数体内的变量,而不是现在在ES5 arguments.callee中弃用的变量。

但是,命名的函数表达式是不正确,并且在Internet Explorer中实现时出现问题,并且在针对这些浏览器时通常应该避免。有关更多信息,请参阅Juriy Zaytsev's excellent article on the subject

+0

用于提及内部作用域中函数名称的可见性。 – fcalderan 2012-03-12 12:59:50

+0

+1,正如在Mozilla的官方文档中看到的那样''函数名称只能在函数的主体中使用。“#:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions#差异 – 2014-11-10 09:41:35

7

调试应用程序时,使用“named”匿名函数时,更容易知道调用堆栈中的内容是什么。所以这是一种给匿名函数命名的方法,用于调试目的。

试试这个,看看调用堆栈在调试器:

myDiv = document.getElementById("myDiv"); 

myDiv.onclick = function OnClick(){ 
    debugger; 
    //do something 
} 
+1

我做了一个小提示,证明你的观点:http://jsfiddle.net/fqeDG/。 谢谢! – 98374598347934875 2012-03-12 12:55:29

+4

小心在IE <9中使用命名函数表达式:这些浏览器中的实现被破坏。 http://kangax.github.com/nfe/ – 2012-03-12 13:01:27

+0

详细说明,onclick属性的函数分配在ie的早期版本中被打破,而不是语法函数OnClick(){}。 – Zoidberg 2012-03-12 14:36:40

2

,因为它使调试更加方便它们命名匿名函数。调试时,您会在调用堆栈中看到对“foo”的调用,而不是一堆对“匿名”的调用。

2

我能想到的唯一原因就是给函数一个想要的名字。这有助于调试,因为检查员使用功能对象的name属性。试试这个:

var bar = function foo(){}; 
console.log(bar.name); // foo 

如果你把里面的foo的一些实际的代码和一个断点在浏览器中添加JavaScript调试器,你会看到的功能调用堆栈foo

0

函数定义(或文字)有4个部分。 1.保留字function 2.可选名称,可由调试器或函数用于递归调用。 3.参数和4.函数主体包装{ }

函数范围foo之外不存在。但是由于您将函数分配给变量栏,因此您可以使用方法调用栏来调用它,并且由于已定义了栏,因此您可以将其打印出来。

如果您在JavaScript有兴趣,你真的应该考虑让Douglas Crockford's book Javascript: The Good Parts

相关问题