关于闭包:jQuery美元符号($)作为函数参数?

jQuery dollar sign ($) as function argument?


我理解JavaScript闭包,我在原生JS中看到过这个:

1
2
3
(function () {
  // all JS code here
})();


但是,添加jQuery spice有什么作用呢?

1
2
3
(function ($) {
  // all JS code here
})(jQuery);



当你看到:

1
2
3
(function() {
  // all JS code here
})();


它被称为自我调用的匿名函数。该函数在解析后立即执行,因为最后添加了()(这就是你运行js函数的方式)。


请注意,额外的外括号只是惯例,您也可以将它写成:

1
2
3
function() {
  // all JS code here
}();


但是这个惯例在各地都被广泛使用,你应该坚持下去。

1
2
3
(function($) {
  // all JS code here
})(jQuery);


这里,$映射到jQuery对象,以便您可以使用$而不是jQuery关键字。你也可以在那里放一些其他角色:

1
2
3
(function(j) {
  // all JS code here
})(jQuery);


这里,j被映射到jQuery对象。


另请注意,为自调用函数指定的参数仍在该函数的范围内,并且不与外部作用域/变量冲突。


我写了一篇关于这个主题的文章,请查看:

  • Javascript自执行功能



它是一种将jQuery映射到$的方式,以便不是页面中的所有代码都能看到它。


也许你有一个现有的脚本使用你想要重用的jQuery,但你也使用在同一页面中也使用$的原型。


通过使用该构造中的代码包装任何jQuery,您可以为包含的部分重新定义$ to jQuery,而不会与页面中的其他代码发生冲突。


1
2
3
(function() {
   // all JS code here
})();


是一个立即调用的函数表达式(IIFE),发音为"iffy"。有些人还称他们为"匿名,自动执行的功能",或称"自动执行功能"。

1
2
3
(function(aParameter) {
   alert(aParameter);  // will alert"an argument"
})("an argument");


这是一个IIFE,它接受参数'aParameter'并传递参数"一个参数"。

1
2
3
(function($){
   alert($(window).jquery);  // alert the version of jQuery
})(jQuery);


这个是类似的,但"jQuery"(jQuery对象实例)是IIFE的参数,在这种情况下,jQuery作为'$'参数传递。通过这种方式,只需输入'$',IIFE的主体就可以访问jQuery及其成员。这是一个常见的jQuery约定,人们编写jQuery插件以这种方式维护这个约定是很常见的。


上面的代码不仅维护了jQuery约定,还确保了你和其他任何人都不会意外地违反该约定。例如,采用以下代码:

1
2
3
var $ = function() {
   alert('foo');
}


这段代码将'$'转换为绝对不是jQuery的东西。如果有人在插件代码之外的其他代码中执行此操作,然后您没有明确地将jQuery作为'$'传递给您的插件,那么您将无法像通常那样使用'$'作为jQuery。



以这种方式将jQuery传递给闭包有两个原因。


到目前为止,最重要的一点是它使您的代码在使用jQuery的"无冲突"模式的页面上工作,这允许使用jQuery以及希望控制$全局的其他库。因此,在编写jQuery插件时强烈建议使用(function($) { ... })(jQuery)技术。


第二个原因是它使$成为自执行函数范围内的局部变量,局部变量访问(全局变量)访问速度(略微)快于全局变量访问。就个人而言,我不认为这是一个非常令人信服的理由 - 我无法想象使用jQuery而不是DOM方法的开销是可以接受的,但是访问jQuery作为全局变量的情况不会。 :-)


我会说在没有编写插件时使用这种技术的最佳理由是为了保持一致性 - 如果你不习惯这样做,你就不太可能忘记这样做了。此外,你永远不知道什么时候你有机会回收代码!