我正在学习jQuery,并且正在尝试理解以下代码结构。
if(jQuery) (function($){
$.extend($.fn, {
MyPlugin: function(a, b) {
....
}
});
})(jQuery);
据我所知,这首先检查jQuery对象是否存在。如果是,它定义了一个内联函数,它使用'fn'属性扩展jQuery对象。
我在其他几个地方看到过这个问题for example here,但是我不理解的问题没有得到解决。在哪里我感到困惑......
- 为什么特殊的jquery“$”对象传递给初始函数?
- 为什么内联函数传递了jQuery对象(在最后一行)?即:(function($){...})(jQuery);
感谢。
答案 0 :(得分:5)
它只会创建一个闭包,您可以jQuery
引用$
,即使它位于noConflict mode。
在jSang的回答(+1)的plugin authoring中也有解释。
从技术上讲,它只是定义了一个匿名函数,该函数接受一个名为$
的参数并立即调用它作为唯一参数传递jQuery
,因此$
充当{{1}的别名在此函数的范围内 - 请注意,此闭包内的全局范围中的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);
别名为jQuery
,在您的用户具有Prototype或使用$
全局命名空间的其他库的情况下非常有用,实例。这使您的插件更加坚固且不易出错。
无论jQuery是否控制$ variable,都可以使用闭包,因此它非常适合插件创作。
想象一下,如果你的一个最终用户在noConflict模式下使用jQuery而使用$
命名空间使用Prototype,并且你的插件试图用jQuery方法扩展$
?混乱和小马!
当然,您可以跳过关闭并将所有$
替换为$
,但这会让您的代码更长,对许多开发人员来说也不太可读。
此外,如果您无法理解闭包,How do JavaScript closures work?会有很多有用的答案,即使这个问题不需要太多关于闭包的深入知识。 jQuery
答案 1 :(得分:4)
我会尽力回答这些问题。我在iPad上,如果我遗漏了一些技术细节,请耐心等待。这些要点有点简化,但它们有助于描述发生了什么:)
希望有所帮助:)
答案 2 :(得分:3)
这将回答你的问题: http://docs.jquery.com/Plugins/Authoring
答案 3 :(得分:3)
您正在寻找的是使用新插件扩展jQuery“您正在扩展的部分 $。fn ”。它被包裹在封闭块中。
(function($){
//do sth
})(jQuery);
以上代码是您必须考虑的部分。要描述它,请参见下面的示例:
<强> 1。声明一个函数并调用它
var fn = function(b){ /*do sth like alert(b)*/ };
fn('hiiii');
<强> 2。语法较短
(function(b){ /*do sth like alert(b)*/ })('hiiii');
现在,如果您将 b 替换为 $ 并使用 jQuery 传递参数'hiiii',您最终会:
(function($){ /*do sth with $*/ })(jQuery);
正如您在第一个示例中看到的那样 b 是方法参数,'hiiii'是在调用时传递的参数。与上面的内容相同, $ 是方法参数, jQuery 是调用时传递的参数。
原因是避免与其他库发生冲突,因为$已在几乎所有JS库中广泛使用。所以你可以在其他库中使用jQuery。
如果您想了解有关如何开发插件的更多信息,请转到this post