jquery源码中noConflict(防止$和jQuery的命名冲突)的实现原理
最近在看jquery源码分析的视频教学,希望将视频中学到的知识用博客记录下来,更希望对有同样对jquery源码有困惑的童鞋能有一点点的帮助(我是从一个小白的角度出发,感觉挺容易理解的,顺带说下视频中jquery源码选取的是2.0.3版本)。
我们都知道,使用$和jQuery效果是一样的,比如:
1 <button id="btn">点我</button> 2 $("#btn").click(function(e) { 3 console.info(e.type); 4 }); 5 jQuery("#btn").click(function(e) { 6 console.info(e.type); 7 });
为什么是这样子呢?因为jquery源码中是包在一个立即调用的函数表达式中(一个闭包),对外暴露的接口就是$和jQuery,将这两个属性绑定在window下:
1 window.jQuery = window.$ = jQuery;
因为别的库也用$或者jQuery符号,比如prototype.js,所以同时引prototype和jquery就有可能造成命名冲突,jquery解决命名冲突问题的代码如下:
1 (function(window, undefined) 2 3 4 var 5 // Map over jQuery in case of overwrite 6 _jQuery = window.jQuery, 7 8 // Map over the $ in case of overwrite 9 _$ = window.$; 10 11 jQuery.noConflict = function( deep ) { 12 if ( window.$ === jQuery ) { 13 window.$ = _$; 14 } 15 16 if ( deep && window.jQuery === jQuery ) { 17 window.jQuery = _jQuery; 18 } 19 20 return jQuery; 21 }; 22 })(window);
noConflict是jquery通过extend扩展的工具方法(静态方法),与ajax方法一样,调用方法为$.noConflict()或者jQuery.noConflict(),不带参数是对$的处理,带参数true时是对jQuery的处理,这个函数返回值就是jQuery对象。jquery源码中用_jQuery和_$来保存全局中jQuery和$的值,因为jquery对外接口的时候将$和jQuery全部挂在window上,window.$和jQuery始终是相等的,都等于jquery源码中的jQuery对象,所以jquery会放弃对$的使用(我不用$了,你们用吧),将_$中保存的值赋给window.$;如果加一个参数true的时候,jquery会放弃jQueryde的使用,将_jQuery中保存的值赋给window.jQuery(2种情况都会返回jQuery对象,我们还是可以用继续用$来用别的库的方法,并且用另外的变量来保存返回的jQuery对象来使用jquery的方法。
1 <script> 2 var $ = { 3 sayName: function() { 4 console.info('我是prototype中的$'); 5 } 6 }; 7 </script> 8 <script src="jquery.2.0.3.js"></script> 9 <script> 10 var iAmRealJQ = $.noConflict(); 11 $.sayName(); // 我们还可以使用自定的$对象的方法 12 console.info(iAmRealJQ); // 我们还可以用jquery源码的jQuery对象来实例化一个新对象 --> 13 </script>
1 <script> 2 var jQuery = { 3 sayName: function() { 4 console.info('我是某个库中的jQuery'); 5 } 6 }; 7 </script> 8 <script src="jquery.2.0.3.js"></script> 9 <script> 10 var iAmRealJQ = jQuery.noConflict(true); 11 jQuery.sayName(); // 我们还可以使用自定的jQuery对象的方法 12 console.info(iAmRealJQ); // 我们还可以用jquery源码的jQuery对象来实例化一个新对象 13 </script>