理解基本的jQuery结构

bli*_*ile 2 javascript jquery jquery-plugins

我正在学习jQuery,并试图理解以下代码结构.

if(jQuery) (function($){
    $.extend($.fn, {
        MyPlugin: function(a, b) {
        ....        
        }
    });
})(jQuery);
Run Code Online (Sandbox Code Playgroud)

据我所知,这首先检查jQuery对象是否存在.如果是,它定义了一个内联函数,它使用'fn'属性扩展jQuery对象.

我已经在其他几个地方看过这个问题,例如这里,但我不理解的问题没有得到解决.我在哪里感到困惑......

- 为什么特殊的jquery"$"对象传递给初始函数?

- 为什么内联函数传递了jQuery对象(在最后一行)?即:(function($){...})(jQuery);

谢谢.

Fab*_*tté 5

简单的解释

它只是创建了一个封闭在那里你可以参考jQuery使用$,即使是在noConflict模式.

还在jSang的答案(+1)的插件编写中进行了解释.

从技术上讲,它只是定义了一个匿名函数,该函数接受一个被$调用的参数并立即将其jQuery作为唯一参数传递,因此$作为jQuery该函数范围内的别名- 请注意,$此闭包内的全局范围内无法访问.

这意味着,如果您$在全局范围内使用Prototype,则无法使用$闭包内部访问Prototype ,因为$引用jQuery 的本地范围优先.

当然,如果你需要在闭包中使用另一个库的方法,你可以使用2个参数定义它:(function($j, $p) {并且(jQuery, $)假设另一个库正在使用$命名空间,则调用它.或者更简单地说,将闭包的局部范围var别名与其他库的全局范围var:不同(function($j) {,这意味着全局$仍然可以在函数的范围内访问.请注意,后一种效果可能是不合需要的,因为您无法完全确定用户分配的内容,$除非您在文档中明确地将其写入.我想需要多个库的插件有点偏离主题所以让我们留下它.


稍微详细一些

来自noConflict docs页面的实际闭包示例:

jQuery.noConflict();
(function($) { 
  $(function() {
    // more code using $ as alias to jQuery
  });
})(jQuery);
Run Code Online (Sandbox Code Playgroud)

那封别名jQuery作为$其范围内,如果非常有用您的用户有原型或使用另一个库$全局命名空间,例如.这使您的插件更加坚固且不易出错.

无论jQuery是否控制$ variable,都可以使用闭包,因此它是插件创作的理想选择.

想象一下,如果你的一个最终用户在noConflict模式下使用jQuery而使用$命名空间使用Prototype ,你的插件是否尝试$使用jQuery方法进行扩展?混乱和小马!

当然,你可以跳过关闭和替换所有$jQuery,但它会让你的代码的时间更长,不易阅读到很多开发者.

此外,JavaScript闭包如何工作?如果您无法理解闭包,那么它有很多有用的答案,即使这个问题不需要太多关于闭包的深入知识.:)