为什么JavaScript函数声明(和表达式)?

时间:2012-03-12 12:38:01

标签: javascript

我见过其他人使用以下模式。

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

但为什么呢?如果两者都被宣布,我可以看到这一点,但事实并非如此。原因是什么?

5 个答案:

答案 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