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

IT技术 javascript
2021-01-28 03:26:46

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

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

但为什么?如果两者都被声明,我可以看出这一点,但他们没有。原因是什么?

5个回答

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

但是,在 Internet Explorer < 9 中,命名函数表达式的实现不正确且有问题,当您针对这些浏览器时,通常应避免使用有关更多信息,请参阅Juriy Zaytsev 关于该主题的优秀文章

+1 用于提及内部作用域中函数名称的可见性。
2021-03-21 03:26:46
+1,如 Mozilla 的官方文档"The function name can be used only within the function's body." developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
2021-04-11 03:26:46

在调试应用程序时,当使用“命名”匿名函数时,更容易了解调用堆栈中的调用内容。因此,这是一种为调试目的为匿名函数命名的方法。

试试这个并在调试器中查看调用堆栈:

myDiv = document.getElementById("myDiv");

myDiv.onclick = function OnClick(){
    debugger;
    //do something
}
详细地说,将函数分配给 onclick 属性在 ie 的早期版本中被破坏,而不是语法 function OnClick() {}。
2021-03-16 03:26:46
当心在 IE < 9 中使用命名函数表达式:这些浏览器中的实现被破坏了。kangax.github.com/nfe
2021-03-19 03:26:46
我在 IE 8 及更少版本中使用过 function () {} ,它对我来说很好用。它是否无法编译,请详细说明损坏的是什么。
2021-04-08 03:26:46
@Zoidberg:详细信息都在我链接到的文章中(kangax.github.com/nfe)。虽然它通常可以工作,但它的问题很微妙,这意味着它可能会导致难以发现的错误。
2021-04-09 03:26:46
@Zoidberg:不,我不是这个意思。语法var foo = function bar() {};本身在 IE < 9 中肯定被破坏了。此外,DOM0 事件处理程序属性(例如myDiv.onclick = function() {};)在 IE 中工作正常。我想您正在考虑setAttribute()(eg myDiv.setAttribute("onclick", "alert('click')");),它在旧 IE 中损坏。
2021-04-13 03:26:46

他们命名一个匿名函数是因为它使调试更容易。调试时,您将在调用堆栈中看到对“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