【jquery源码三】jQuery是如何创建方法和扩展方法

简介:

前言:jQuery下的方法有很多,而且都很实用。比如each方法,我们可以$.each()这样去使用,也可以$('div').each()这样去使用,两者有什么区别呢?



  
  
  1. var jQuery = function( selector, context ) {
  2. return new jQuery.fn.init( selector, context, rootjQuery );
  3. }
  4. jQuery.each = function(){}

前者是jQuery下的方法,可以直接使用,我们习惯性称为工具方法;

--------



  
  
  1. jQuery.fn = jQuery.prototype = {
  2. constructor: jQuery,
  3. init: function(){}
  4. }
  5. jQuery.fn.each = function(){
  6. }

后者是jQuery原型下的方法,需要实例jQuery对象后使用,我们习惯性称为jQuert实例对象方法。


一、模拟jQuery创建方法、扩展方法。



  
  
  1. ( function(window,undefined){
  2. var jQ = function(selector){
  3. return new jQ.fn.init(selector);
  4. };
  5. jQ.fn = jQ.prototype = {
  6. jquery: '2.0.3', //jquery版本号信息
  7. constructor: jQ, //添加构造器属性
  8. length:0, //初始length属性
  9. selector:'', //初始selector属性
  10. init: function(selector){
  11. //初始化jQuery对象
  12. },
  13. toArray: function(){},
  14. get: function(){},
  15. pushStack: function(){},
  16. each: function(){},
  17. ready: function(){},
  18. slice: function(){},
  19. first: function(){},
  20. last: function(){},
  21. eq: function(){},
  22. map: function(){},
  23. end: function(){},
  24. push: function(){},
  25. sort: function(){},
  26. splice: function(){}
  27. };
  28. jQ.fn.init.prototype = jQ.fn;
  29. jQ.extend = jQ.fn.extend = function(){
  30. }
  31. jQ.extend({
  32. each: function(){},
  33. type: function(){},
  34. parseJSON: function(){}
  35. /*.............*/
  36. });
  37. jQ.fn.extend({
  38. attr: function(){},
  39. removeAttr: function(){},
  40. addClass: function(){},
  41. removeClass: function(){},
  42. toggleClass: function(){},
  43. val: function(){},
  44. css: function(){},
  45. on: function(){}
  46. /*.............*/
  47. });
  48. window.$$ = jQ;
  49. })( window );

①、像jQ原型下有一些比较重要的方法,而且不会经常需要修改、优化,或者删除的方法。

②、而如果要继续添加、扩展方法。都是通过extend()去扩展方法。



  
  
  1. jQ.extend = jQ.fn.extend = function(){
  2. }

③、扩展工具方法



  
  
  1. jQ.extend({
  2.      each: function(){},
  3. type: function(){},
  4. parseJSON: function(){}
  5.      /*.............*/
  6. });

④、扩展jQuery对象方法



  
  
  1. jQ.fn.extend({
  2.      attr: function(){},
  3.      removeAttr: function(){},
  4.      addClass: function(){},
  5.      removeClass: function(){},
  6.      toggleClass: function(){},
  7.      val: function(){},
  8.      css: function(){},
  9.      on: function(){}
  10.      /*.............*/
  11. });

这样使得代码的更好维护,如果要添加方法只需要在extend中去操作,而不需要在核心代码中去操作。


二、extend扩展方法源码

在研究extend源码之前,来看看extend几种用法。

1、简单的说extend有四种用法:

①、扩展jquery工具方法

②、扩展jQuery实例对象方法

③、浅拷贝

④、深拷贝

2、进行细分的话,extend有以下几种情况



  
  
  1. var obj1 = { name: 'freddy', hobit:[ "basketball"], sex: null };
  2. var obj2 = { age: 18 };
  3. var obj3 = {};
  4. var obj4 = {};
  5. var obj5 = {};
  6. $.extend({}); //①扩jQuery展工具方法
  7. $.fn.extend({}); //②扩展jQuery实例对象方法
  8. $.extend(obj3,obj1); //③浅拷贝
  9. $.extend(obj3,obj1,obj2); //③浅拷贝多个对象
  10. $.extend( true,obj4,obj1);          //④深拷贝
  11. $.extend( true,obj4,obj1,obj2);          //④深拷贝多个对象
  12. $.extend(obj5,{ name: 'nick'},{ age: 18});   //⑤扩展对象
  13. console.log(obj3);
  14. console.log(obj4);
  15. console.log(obj5);

对于浅拷贝、深拷贝不熟悉的可以看看我以前的文章【JavaScript】对象引用、浅拷贝、深拷贝详解

3、直接上extend源码(这里的目标对象为“被扩展的对象”或者“拷贝别人”的对象)



  
  
  1. jQuery.extend = jQuery.fn.extend = function() {
  2.      var options, name, src, copy, copyIsArray, clone,
  3. target = arguments[ 0] || {}, //设置第一个参数为目标对象
  4. i = 1,    //i为1是浅拷贝情况下,被拷贝的对象是arguments[1],从二个参数开始
  5. length = arguments.length,
  6. deep = false; //默认是浅拷贝
  7.      //$(true,arr4,arr1) || $(true,arr4,arr1,arr2);
  8.     if ( typeof target === "boolean" ) { //深拷贝情况第一个参数为true,布尔类型
  9. deep = target;    
  10. target = arguments[ 1] || {}; //目标对象变成第二个参数了
  11. i = 2; //被拷贝对象是arguments[2],从第三个参数开始
  12.     }
  13.      //看目标对象是否是对象
  14.      if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
  15. target = {};
  16.     }
  17.      //$.extend({}) || $.fn.extend({}) 扩展方法
  18.     if ( length === i ) { //只有一个参数的情况
  19. target = this; //目标对象变成了$ 或者 $.fn
  20. --i;             //i变成0
  21.     }
  22.      for ( ; i < length; i++ ) { //for循环用于解决->拷贝多个对象的情况
  23. if ( (options = arguments[ i ]) != null ) { //如果该参数对象不为undefined或null
  24.      for ( name in options ) {
  25. src = target[ name ]; //保存目标对象属性
  26. copy = options[ name ]; //保存该属性的值
  27. //如果出现$.extend(obj1,{ name:obj1 }); 跳过本次循环
  28. if ( target === copy ) {
  29. continue;
  30. }
  31. //如果该属性下的值是"对象自变量"或者"数组",就进行深拷贝
  32. if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { //深拷贝
  33.      if ( copyIsArray ) { //如果该属性下的值是"数组"
  34. copyIsArray = false;
  35. clone = src && jQuery.isArray(src) ? src : [];
  36.     } else { //如果该属性下的值是"对象自变量"
  37. clone = src && jQuery.isPlainObject(src) ? src : {};
  38.     }
  39.     target[ name ] = jQuery.extend( deep, clone, copy ); //然后进行递归操作
  40. } else if ( copy !== undefined ) { //浅拷贝
  41.     target[ name ] = copy;
  42. }
  43. }
  44.     }
  45. }
  46. return target;
  47. };
注释写上去之后,一些都明了了,也并没有什么难点。如果有不明白的地方可以下方留言。


三、扩展方法



  
  
  1. <body>
  2. <script src="https://cdn.bootcss.com/jquery/2.0.3/jquery.js"> </script>
  3. <script>
  4. $.extend({
  5. freddy: function(){
  6. console.log( '扩展jQuery工具方法');
  7. }
  8. });
  9. $.fn.extend({
  10. freddy: function(){
  11. console.log( '扩展jQuery实例对象方法');
  12. }
  13. });
  14. $.freddy();
  15. $( document).freddy();
  16. </script>
  17. </body>

运行结果

这样是不是很方面,就算不熟悉jquery源码,也能很快扩展出自己想要的方法。不过这里要注意的是,如果扩展的方法名如果跟jQuery原生的方法名重名(如css,attr),会发生我们扩展的方法覆盖了原生的jQuery方法。   


原文发布时间为:2018年06月30日

原文作者:穆弘

本文来源CSDN如需转载请联系原作者

相关文章
|
JavaScript 前端开发
|
JavaScript
表单验证Jquery扩展方法类
/** 表单数据验证 **/ $.fn.Validform = function () { var Validatemsg = ""; var Validateflag = true; $(this).
1255 0
|
JavaScript 前端开发 数据格式
为Jquery类和Jquery对象扩展方法
jquery.fn.extend与jquery.extend jQuery为开发插件提拱了两个方法,分别是: JavaScript代码 jQuery.fn.extend(object);    jQuery.extend(object);    jQuery.extend(object); 为扩展jQuery类本身.为类添加新的方法。
814 0
|
6月前
|
JavaScript
jQuery图片延迟加载插件jQuery.lazyload
jQuery图片延迟加载插件jQuery.lazyload
|
1月前
|
JavaScript
jQuery 树型菜单插件(Treeview)
jQuery 树型菜单插件(Treeview)
59 2
|
5月前
|
设计模式 JavaScript 前端开发
必知的技术知识:jQuery插件开发精品教程,让你的jQuery提升一个台阶
必知的技术知识:jQuery插件开发精品教程,让你的jQuery提升一个台阶
60 1
|
1月前
|
JavaScript 前端开发
jQuery Growl 插件(消息提醒)
jQuery Growl 插件(消息提醒)
40 4
jQuery Growl 插件(消息提醒)