8

我见过这样写的 Javascript 中的自调用函数:

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

但我也看到它们是这样写的:

(function () {
    // bar!
}());

从语法上讲,它们做的事情完全相同。实际上,我个人的习惯是第一种格式,但是我应该注意这两种格式有什么区别吗?像浏览器扭结或其他什么?

例如,一件非常微不足道的事情是,如果第二种格式应该可靠地工作,那么这意味着这样的事情也应该是可能的:

function () {
    // shut the front door! saved two characters right there!
}();

不过,这会极大地损害可读性。

4

6 回答 6

4

第一的:

就像您假设的那样,您的自调用匿名函数的前两个版本之间绝对没有区别。没有浏览器链接,怪癖,只是归结为个人喜好(顺便说一句,Douglas Crockford 将后一种形式称为“狗球”)。

第二:

function() {
}()

不会按设计工作,因为该语句创建了一个函数 statement/declaration。您需要一个函数表达式来立即调用自身。要创建函数表达式,您可以执行多项操作。将整个语句放在括号中是一种方法,但你也可以写

!function() {
}()

或者

+function() {
}

所有这些运算符都会生成一个表达式。

于 2012-09-06T16:58:13.813 回答
1

前两个是相同的,但如果我没记错的话,其中一个是 jsLint 的首选(我认为是第二个)。

第三个在大多数解释器中引发语法错误,但还有其他变体:

!function() {
    alert('I’m executing myself!');
}();

var noname = function() {
    alert(noname); // undefined!
}();

​您可以用 or 替换!+它们-都不会让 Crockford 高兴)

于 2012-09-06T17:05:23.533 回答
0

这主要是一个约定问题。

(function () {}());<- 执行前少一个堆栈帧(也许)

(function () {})();<- 在括号外执行,所以在执行前有一个很小的框架,虽然我不喜欢这种风格,但 IMO 它在视觉上是断开的。

function () {}(); <- 这只是 IMO 的坏习惯,这不是很明显这是一个主要是由于约定的IIFE,但这也有一个问题,如果你在表达式之前忘记了一个分号,它会在某些条件下默默地分配变量值未定义。

例子:

var x = 0,
    y = 1,
    z = 3,

function () {
    alert("Z is now undefined, instead of throwing a syntax error.");
}();

正如 Andre Meinhold 所说,这不在表达位置。

于 2012-09-06T16:58:41.107 回答
0

务实地说,JSLint 会抱怨第一种格式而更喜欢第二种格式。除此之外,这真的是个人喜好和一致性是这里的关键。

第三种格式将导致 SyntaxError,因此您不能使用它。那是因为您创建的是函数声明,而不是函数表达式。它是您在使用立即函数模式时调用的函数表达式。

于 2012-09-06T17:02:58.467 回答
0

Crockford说要使用(function () {...}()).

这只是一种风格选择,但就社区的利益达成一致意见(冒着引发激烈战争的风险)为什么不使用 Crockford 的呢?

于 2012-09-06T17:06:31.880 回答
0

另外,请记住,这(function () { }());会增加潜在的混乱。因为在一个长函数中,不注意的人可能会看到两个右括号,只有一个被打开。

于 2012-09-06T17:06:59.460 回答