2

我在调用 JavaScript 函数表达式时看到了这些不同的模式:

模式#1

var global = function () {
    return this;
}();

模式#2

var global = (function () {
   return this;
}());

模式#3

var global = (function () {
    return this;
})();

在我的测试中,一切似乎都有效(至少在大多数当前浏览器中)。就我的“口味”而言,模式#3 更好,因为它比#1 更明确,并且它在实际调用它之前返回函数,而不是#2。

但是我在徘徊,如果有一个更喜欢或更正确的...

4

3 回答 3

2

所以,最初的问题是下面的代码:

function () {

}();

引发异常。这是因为 JS 解析器无法自动判断是函数声明还是函数表达式。您描述的所有模式都用于明确告诉 JS“嘿,伙计,这是一个表达式”。但是在您的特定情况下,您没有这个问题,因为如果您前面有一个变量,JS 完全能够理解这是一个表达式,而不是一个声明,并且它不会引发任何语法错误。

在那种特定情况下,不需要任何“破解”,您可以简单地拥有:

var _global = function () {

}();

就是这样。现在的问题是:当您需要在没有任何变量的情况下立即调用函数时,使用哪种“hack”?您描述的所有模式都可以,Crockford 更喜欢这个:

(function(){

}());

这对我来说很有意义,至少因为你有一个完全隔离的块,与:

(function(){

})();

但是,如果您将代码与其他脚本结合在一起,或者您有以前的代码,如果它们最后不使用分号,您可能会遇到一些问题:

a = b + c
(function() {

}());

在这种情况下,JS 考虑c一个函数的调用:

a = b + c(function() { }());

为了避免这种情况,开发人员通常会在前面添加一个分号,以确保安全:

;(function() {

}());

我个人更喜欢一些运算符,比如 bang (!):

!function () {

}();

这样,您就不会遇到使用括号的问题。更少的字符,给我一种“执行”的感觉。但是,就像其他方法一样,这是一种技巧,而且是个人品味的问题。例如,Crockford 不喜欢 A LOT 那种轰轰烈烈的东西。

于 2012-06-03T16:06:17.503 回答
0

它们都可以正常工作,您可以使用其中任何一种,但Crockford推荐的模式是模式 #2:

var global = (function () {
   return this;
}());

我个人觉得 Pattern #3 很容易使用,因为它很容易理解:

var global = (function () {
    return this;
})();

顺便说一句,还有其他使用 , 等字符的模式/!速记+

! function(){
  return this;
}();
于 2012-06-03T15:31:34.553 回答
0

我更喜欢模式一,因为在将函数定义为对象的属性时,你的语法会变得非常冗长。模式#1 很容易遵循;你定义一个函数然后调用它。()模式 3 做同样的事情,但要遵循额外的一组。在我看来,这种冗长会降低生产力。

正如您所说,它们都是正确的,但我发现记住“奥卡姆剃刀”=> 当所有事物都相同时,更简单的解释(表达式)比更复杂的解释更好。

于 2012-06-03T15:32:59.140 回答