命名函数声明有什么好处吗?

时间:2015-02-24 13:12:05

标签: javascript function

一个。 function foo(){}

B中。 var foo = function foo(){}

我以A方式编写所有JavaScript函数,因为我认为B是多余的。我的同事喜欢进入并进行大规模查找/替换以重写我的功能,例如B,因为他说这是根据airbnb的最佳做法。

  1. 两者之间的基本/实际区别是什么?

  2. 这样做是否存在破坏我的代码的危险?

  3. 这是一个比另一个更好的做法(你能引用任何来源)吗?


1 个答案:

答案 0 :(得分:4)

序言:您的名为函数声明。他被称为命名函数表达式(NFE)。这些内容在this question and its answers中有详细讨论,但针对您的具体问题:

  

......根据airbnb,他说这是最好的做法......

如果他在谈论these Airbnb style guidelines,我认为没有任何东西可以支持这种说法。我确实看到了一些你可以 误读 的东西,但这会被误读。它表示不在控制流程块中声明函数,例如:

// bad
if (currentUser) {
  function test() {
    console.log('Nope.');
  }
}

这是非常正确的,根据当前的规范,这不仅是坏的,而是无效。您只能在范围的顶层声明函数(例如,在ifwhilefor等所有控制流结构之外的全局范围内;或者在所有控制流结构之外的函数的顶层)。上面的示例无效,因为它位于连接到if的块中。 (在ES6中,仅适用于Web引擎,非常特定的情境子集中的tolerated - TL; DR:不要这样做。 )

但这并非一揽子“不要使用函数分解”,而不是远程。

  

两者之间的基本/实际区别是什么?

您的表单在进入声明函数的作用域时被处理,执行任何分步代码之前(有时称为“提升”)。当在逐步执行代码时遇到函数表达式时,他的表单将在稍后执行

  

这样做是否存在破坏我的代码的危险?

是的,这个有效的代码:

foo();
function foo() {
    // ...
}

...如果重写为:

会破坏
foo(); // <== Fails
var foo = function foo() {
    // ...
}

...因为函数声明提升已经消失(var仍然存在提升),因此当您尝试调用时,foo变量的值为undefined

另外,某些浏览器会使NFE 错误,从而创建two functions instead of one。例如,IE8和旧版本的Safari一样。我所知道的所有现代浏览器都是正确的(现在)。

最后,他重写你的代码依赖于自动分号插入的恐怖(为了正确地重写它,他需要在函数体之后添加;)。 ASI并不完美。依靠它也传统上搞砸了minifiers,虽然这些天大多数minifiers正确地处理它(从技术上讲,不处理它是minifier中的一个错误)。

  

一种比另一种更好的做法(你能引用任何来源)吗?

这是一个主观的意见问题,除了上面提出的实际问题(由于删除吊装和NFE而破坏)。