立即调用函数表达式:括号放在哪里?

Immediately Invoked Function Expression: Where to put the parenthesis?

我看过IIFE的写法:

(function() {
    console.log("do cool stuff");
})();

以及:

(function() {
    console.log("do more cool stuff");
}());

在我使用它们的任何情况下,它们似乎都以相同的方式工作,但在某些情况下,我被告知一种方式是正确的,另一种方式是错误的,反之亦然。有没有人有任何可靠的理由或逻辑来说明它是一个订单而不是另一个订单?在某些情况下,在函数体关闭之后但在调用括号发挥作用之前,或者在最后一个右括号之后但之前,是否可能会有更多的事情发生?我主要在 Angular 模块闭包中使用这些,但似乎无法找到任何真正的理由去一种或另一种方式,想知道是否有人有不同的经验。

简答:没关系,只要你把它们放在那里。

长答案:除了箭头函数外,这无关紧要,因为对于 JavaScript 来说,唯一重要的是它们在那里。这样做的原因是语言规范定义如果您声明一个 named 函数,则语句必须仅以 function 关键字开头。因此,像这样定义 IIFE 是违反规范的:

function () {}();

解决方法是将整个内容括在括号中,这样语句就不再以 function 关键字开头。您可以通过使用

来实现
(function () {})();

以及使用:

(function () {}());

你选择哪一个是完全随意的,因此取决于你。

我(个人)将括号放在函数周围,而不是调用周围,即像这样:

(function () {})();

原因:我想使用最小的代码部分来包装一些仅出于技术原因才需要的东西,这是函数定义,而不是调用。除了规范说你不能 define 那样的函数之外,它与调用函数无关。因此,我认为如果包装定义而不是调用会更清楚。

编辑 但是,对于 es6 中的箭头函数,调用必须在包装器之外。它在包装器内部会导致调用的左括号出现意外的标记错误。不完全清楚为什么会这样。