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

7

我看到过以下形式的IIFE:

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

除此之外:
(function() {
    console.log("do more cool stuff");
}());

我发现无论在哪种情况下使用它们,它们似乎都是一样的,尽管在某些情况下,我被告知其中一种方法是正确的,而另一种方法是错误的,反之亦然。有没有任何确切的理由或逻辑,可以解释为什么要按照一定顺序编写代码?是否存在一些情况,在函数体关闭后但在调用括号起作用之前或在最终的右括号之后但在其之前可能会出现更多的情况?我主要在Angular模块闭包中使用它们,并且似乎找不到任何真正的理由去选择一种方式或另一种方式,想知道是否有人有不同的经验。


没关系。"有人告诉我一种方法是对的,另一种方法是错的,反之亦然" --- 这只是个人口味问题。 - zerkms
1个回答

9

简短回答:只要你把它们放在那里就可以了。

长话短说:除了箭头函数的情况外,它们的位置并不重要,因为对于JavaScript来说,唯一重要的是它们存在。原因是语言规范定义了一个语句只能以function关键字开头,如果您声明了一个命名函数。因此,像这样定义IIFE是违反规范的:

function () {}();

解决方法是将整个语句用括号包裹起来,这样语句就不再以function关键字开头。您可以使用以下方式实现:
(function () {})();

还可以通过以下方式实现:

(function () {}());

你选择哪一个完全是任意的,因此由您决定。

我个人将括号放在函数周围,而不是调用周围,如下所示:

(function () {})();

理由:我希望使用最小的代码部分来包装一些仅需技术原因的内容,这是函数定义,而不是调用。除此之外,规范指出,您不能以那种方式定义函数,这与调用函数无关。因此,我认为如果您包装定义而不是调用,则更清晰。 编辑: 然而,在es6箭头函数的情况下,调用必须在包装器外部。将其放在包装器内部会导致调用开括号上出现意外的标记错误。对于为什么会这样,机制并不完全清楚。

...还有一个长答案吗? - zerkms
1
我的想法完全一样,哈哈,很想听一个长答案。 - Andrew Clavin
抱歉,我点击了保存太早了。对此感到抱歉 :-( - Golo Roden
1
你知道 ~function() {}() 或者 !function() {}() 的意思吗? - Andrew Clavin
@AndrewClavin,你可以使用~function() {}()或前缀为!来代替括号。这两种方法都可以将声明转换为表达式,并且它们的行为都是相同的。 - zerkms
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接