这种JavaScript立即调用模式的原因是什么?

时间:2011-12-12 14:10:44

标签: javascript jquery design-patterns

在查看SlickGrid源代码时,我遇到了以下模式:

(function ($) {
  var SlickEditor = {

    TextCellEditor: function (args) {
      ...
    },

    LongTextCellEditor: function (args) {
      ...
    }
  };

  $.extend(window, SlickEditor);

})(jQuery);

如果我理解正确,它会使用立即调用来定义各种函数对象,然后将它们合并到全局命名空间中。

所以我可以像这样全局定义我的函数,它会产生相同的效果,对吗?

function TextCellEditor (args) {
  ...
}

function LongTextCellEditor (args) {
  ...
}

我能看到的唯一区别是,在第一个版本中,我可以使用$简写来引用jQuery对象。除此之外,两种情况下的结果都是相同的。

我想知道我是否遗漏了什么。也许还有另外一个很好的理由这样做?

UPDATE :请注意,我意识到使用这种立即调用模式允许使用匿名函数中声明的私有变量。但是在这种情况下没有声明任何变量,并且函数无论如何都被注入到全局范围中。所以我还是想知道是否有任何真正的区别。

有些答案指出,引用局部变量比引用全局变量要快得多。如果我在$构造函数中引用TextCellEditor(),这仍然适用。 $不是TextCellEditor()的本地,因为它是在外部匿名函数的范围内定义的。

所有评论都表示赞赏。

4 个答案:

答案 0 :(得分:3)

不同之处在于,当您使用自己调用的函数(如您所示的函数)时,您正在为私有变量创建局部作用域。

这种类型的自调用函数通常称为闭包,它是许多javascript模式的基础,如模块模式:http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth

您可以在此处阅读有关javascript范围的更多信息:http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting

传递jQuery vairable的原因是2折:

1:通过$调用它更方便,因为它作为局部变量传递,我们可以确定$不是别的东西

2:速度更快 - 本地变量的访问和使用速度比全局变量快得多

作为示例,请查看以下代码块:

var public_and_global=true;

(function(){
  var private_and_local = true;

  function local_func() {
   //can use private_and_local as well as public_and_global
  }

})();

function global_func() {
   //can only use public_and_global
}

答案 1 :(得分:1)

每个人都将他们的整个代码包装在IIFE中。

这是因为每个人都使用局部变量而没有人使用全局变量。

如果您的模块化架构技术恰好是“将模块注入全局范围”,那么您将从IIFE向全球范围注入模块。

答案 2 :(得分:0)

是的,在大多数情况下,它会产生同样的效果。但这种方式很好,因为你总是可以使用速记,但也因为没有变量使全局命名空间混乱。假设我有这个扩展名,以生成唯一的ID:

var UID = (new Date).getTime();
$.uniqueID = function() { return (UID++).toString(16); }

这只会工作,如果我稍后设置UID,可能在另一个脚本中,此功能将不再起作用。好吧,你永远不能确定$的可用性,这也是一个很好的理由。

函数内定义的变量在全局命名空间中不存在。

答案 3 :(得分:0)

马丁说。也:

  

所以我可以像这样全局定义我的函数   有同样的效果,对吧?

没有。这些功能不会在全局名称空间中结束。它们是在本地范围内创建的,然后将它们引用给jQuery。没有任何内容添加到全局范围。

虽然您展示的代码片段没有证明这一点,但除了函数之外,还可以在该范围内定义一些私有数据,例如,固定字符串或查找表,或者这些方法可能需要的任何辅助数据,以及这些函数可以访问这些数据,但是任何其他代码都不能访问这些数据(类似于OO中的“private”),这些数据也不会污染全局名称空间。