一个。 function foo(){}
B中。 var foo = function foo(){}
我以A方式编写所有JavaScript函数,因为我认为B是多余的。我的同事喜欢进入并进行大规模查找/替换以重写我的功能,例如B,因为他说这是根据airbnb的最佳做法。
两者之间的基本/实际区别是什么?
这样做是否存在破坏我的代码的危险?
这是一个比另一个更好的做法(你能引用任何来源)吗?
答案 0 :(得分:4)
序言:您的名为函数声明。他被称为命名函数表达式(NFE)。这些内容在this question and its answers中有详细讨论,但针对您的具体问题:
......根据airbnb,他说这是最好的做法......
如果他在谈论these Airbnb style guidelines,我认为没有任何东西可以支持这种说法。我确实看到了一些你可以 误读 的东西,但这会被误读。它表示不在控制流程块中声明函数,例如:
// bad
if (currentUser) {
function test() {
console.log('Nope.');
}
}
这是非常正确的,根据当前的规范,这不仅是坏的,而是无效。您只能在范围的顶层声明函数(例如,在if
,while
,for
等所有控制流结构之外的全局范围内;或者在所有控制流结构之外的函数的顶层)。上面的示例无效,因为它位于连接到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而破坏)。