你值得了解的JavaScript“继承之jquery”使用方法(代码详解)

 4281

本篇文章给大家了解一下JS-继承之jquery使用方法,小伙伴们可以参考一下。


你值得了解的JavaScript“继承之jquery”使用方法(代码详解)


jquery截止到当前已经 3.3.1 版本了,如今随着各种浏览器的盛行,前端的框架层出不穷,jquery独步天下,老夫写代码只用jquery,拿起代码就是干的辉煌时代已经过去了。

2006 年,jQuery的第一个版本的面世,凭借着简洁、灵活的编程风格受到了开发者的喜爱。而它本身是一个JavaScript框架,它的设计的宗旨是“write Less,Do More”,即倡导写更少的代码,做更多的事情。它封装了JavaScript常用的功能代码,提供一种简便的JavaScript设计模式,优化HTML文档操作、事件处理、动画设计和Ajax交互。

从之前的风靡到如今的被抛弃,究其原因,不少前端工程师表示,对于jQuery来说,大量的操作DOM虽然方便,但是会牺牲很多页面的性能。另一方面,现阶段React、Vue和Angularjs等主流前端框架并不依赖jQuery,都可以独立使用。况且浏览器的兼容问题越来越少,当浏览器兼容不再是问题时,jQuery的价值就大打折扣了

就在微软收购github的 52 天,github改变也已经放弃了jquery,奇替代方案使用了原生的 js:

使用querySelectorAll来查询DOM节点;

使用fetch来代替ajax;

事件处理使用了事件代理;

使用DOM标准化写了polyfill;

使用了自定义元素。


你值得了解的JavaScript“继承之jquery”使用方法(代码详解)


假如不用,学习下还是可以的

本文粗燥的实现jquery的ready、each、bind、``$.fn.extend、$.extend

初始化$

  1. (function (win) {
  2.   var _$ = function (selector, context) {
  3.     /**
  4.      * 通常咱们定义一个 函数 var Fun = function(){}
  5.      * 然后定义一个 Fun.prototype.init = function(){}
  6.      * 那么咱们调用init 的时候 得先要实例化对象 var f = new Fun()
  7.      * 然后f.init()
  8.      * 这里就省去了 var $ = new $()
  9.      */
  10.     return new _$.prototype.Init(selector, context);
  11.   };
  12.   _$.prototype = {
  13.     //初始化$
  14.     Init: function (selector, context) {
  15.       this.elements = [];
  16.       /**
  17.        * 传入的类型是function 就执行ready事件,如果是document 就将document对象插入到this.elements
  18.        * 主要就是判断$(document).ready  和 $(function(){}) 这两种的ready事件的写法
  19.        */
  20.       if (typeof selector === "function") {
  21.         this.elements.push(document);
  22.         this.ready(selector);
  23.       } else {
  24.         var context = context || document;
  25.         var isDocument = (ele) =>
  26.           Object.prototype.toString.call(ele) == "[object HTMLDocument]" ||
  27.           "[object Document]";
  28.         if (isDocument(selector)) {
  29.           this.elements.push(selector);
  30.         } else {
  31.           /**
  32.            * 如果是字符串的话就查询该节点 $('.class') | $('#id')
  33.            */
  34.           if (context.querySelectorAll) {
  35.             var arr = context.querySelectorAll(selector);
  36.             for (var i = 0; i < arr.length; i++) {
  37.               this.elements.push(arr[i]);
  38.             }
  39.           }
  40.         }
  41.       }
  42.     },
  43.     //实现each
  44.     each: function (callback) {},
  45.     //实现ready
  46.     ready: function (callback) {},
  47.     //实现bind
  48.     bind: function (type, callback) {},
  49.   };
  50.   /**
  51.    * 让两个作用域不一样的对象共享一个方法,让他们的原型指向一致,即Init.prototype = _$.prototype
  52.    * 那么原型一致之后 就可以共享this.elements 属性了。
  53.    */
  54.   _$.prototype.Init.prototype = _$.prototype;
  55.   window.= _$;
  56. })(window || global);


ready

  1. //实现ready
  2. ready: function (callback) {
  3.   var isDocument = (ele) => Object.prototype.toString.call(ele) == '[object HTMLDocument]' || '[object Document]'
  4.   //如果已经取得了节点
  5.   if (isDocument(this.elements[0])) {
  6.     if (document.addEventListener) { //判断火狐、谷歌
  7.       /**
  8.        * DOM树构建完成的时候就会执行DOMContentLoaded
  9.        * 页面上所有的DOM,样式表,脚本,图片,flash都已经加载完成了,才会触发window.onload
  10.        * 这也就是$(document).ready() 比 window.onload 执行早的原因
  11.        *
  12.        * arguments.callee 博客里面有一篇文章 [js-递归] 里面专门讲到了,这里不再解释了
  13.        */
  14.       document.addEventListener('DOMContentLoaded', function () {
  15.         document.removeEventListener('DOMContentLoaded', arguments.callee, false)
  16.         callback()
  17.       }, false)
  18.     } else if (document.attachEvent) { //判断IE
  19.       document.attachEvent('onreadystatechange', function () {
  20.         if (document.readyState == 'complete') {
  21.           document.detachEvent('onreadystatechange', arguments.callee);
  22.           callback()
  23.         }
  24.       })
  25.     } else if (document.lastChild == document.body) { //body已经加载完了,就直接回调了
  26.       callback()
  27.     }
  28.   }
  29. },


each

  1. //实现each
  2.  each: function (callback) {
  3.     if (this.elements.length > 0) {
  4.         for (var i = 0; i < this.elements.length; i++) {
  5.         callback.call(this, this.elements[i], i);
  6.         }
  7.     }
  8.  },


bind

  1. //实现bind
  2. bind: function (type, callback) {
  3.   if (document.addEventListener) { //判断火狐、谷歌
  4.     this.each(function (item, i) {
  5.         item.addEventListener(type, callback, false)
  6.     })
  7.     } else if (document.attachEvent) { //判断IE
  8.     this.each(function (item, i) {
  9.         item.attachEvent('on' + type, callback)
  10.     })
  11.     } else {
  12.     this.each(function (item, i) { //其他浏览器 egg: item.onclick = function(){}
  13.         item['on' + type] = callback
  14.     })
  15.   }
  16. }


$.fn.extend/$.extend

$.fn.extend是为查询的节点对象扩展方法,是基于$的原型扩展的方法

$.extend是扩展常规方法,是$的静态方法


官方给出解释:

jQuery.extend(): Merge the contents of two or more objects together into the first object.(把两个或者更多的对象合并到第一个当中)

jQuery.fn.extend():Merge the contents of an object onto the jQuery prototype to provide new jQuery instance methods.(把对象挂载到jQuery的prototype属性,来扩展一个新的jQuery实例方法)

$.fn.extend方法的初衷是我们扩展之后可以用$("").newMetod()这样访问,实际上就是给$原型加一个extend方法。这中间的fn其实类似于命名空间的作用,没什么实际的意义。为的是和$.extend作区分

$.fn.extend

  1. ; (function (win) {
  2.   ...
  3.   _$.prototype.Init.prototype = _$.prototype;
  4.  
  5.    _$.fn = _$.prototype; //把对象挂载到jQuery的prototype属性
  6.  
  7.   var isObj = (o) => Object.prototype.toString().call(o) === '[object Object]';
  8.   $.fn.extend = function (obj) {
  9.     if (isObj(obj)) {
  10.       for (var i in obj) {
  11.         this[i] = obj  //注意这里的this指向是 $.prototype
  12.       }
  13.     }
  14.   }


$.extend

  1. var isObj = (o) => Object.prototype.toString().call(o) === '[object Object]';
  2. ...
  3. _$.extend = function (obj) {
  4.     if (isObj(obj)) {
  5.         for (var i in obj) {
  6.             this[i] = obj[i]; //注意这里的this指向是 $
  7.         }
  8.     }
  9. }

这俩看上去一模一样啊,没啥区别,注释里面已经说了,this指向不同。咱们来看个例子:

  1. <!DOCTYPE html>
  2. <html>
  3.   <head>
  4.     <title>jQuery.extend()与jQuery.fn.extend()区别</title>
  5.     <meta charset="utf-8" />
  6.     <script type="text/javascript" src="jquery.js"></script>
  7.     <!-- 开始扩展 -->
  8.     <script type="text/javascript">
  9.       (function ($) {
  10.         $.extend({
  11.           sayHello: function () {
  12.             console.log("Hello");
  13.           },
  14.         });
  15.         $.fn.extend({
  16.           sayHello: function () {
  17.             console.log("Hello");
  18.           },
  19.         });
  20.       })(jQuery);
  21.     </script>
  22.     <!-- 调用 -->
  23.     <script type="text/javascript">
  24.       $(document).ready(function () {
  25.         //$.extend扩展调用
  26.         $.sayHello();
  27.  
  28.         //$.fn.extend扩展调用
  29.         $("#test").sayHello();
  30.       });
  31.     </script>
  32.   </head>
  33.   <body>
  34.     <div id="test"></div>
  35.   </body>
  36. </html>

这样以来就看的很明白了。jQuery.extend(object); 为扩展jQuery类本身,为自身添加新的方法。$.xxx()

jQuery.fn.extend(object);给jQuery对象添加方法$('#test').xxx()


$.extend常见用法

  1. //在jquery全局对象中扩展一个net命名空间。
  2. $.extend({ net: {} });
  3.  
  4. //方法扩展到之前扩展的Jquery的net命名空间中去。
  5. $.extend($.net, {
  6.   sayHello: function () {
  7.     console.log("Hello");
  8.   },
  9. });
  10.  
  11. //extend方法还有一个重载原型
  12. //extend(boolean,dest,src1,src2,src3...),第一个参数boolean代表是否进行深度拷贝
  13. var a = { protocol: "http", hash: { a: 1, b: 2 } };
  14. var b = { host: "chuchur.com", hash: { b: 1, c: 2 } };
  15.  
  16. var result = $.extend(true, {}, a, b);
  17. console.log(result); //{ protocol: 'http',host: 'chuchur.com', hash: { a: 1, b: 1,c:2 } }
  18.  
  19. var result = $.extend(false, {}, a, b);
  20. console.log(result); //{ protocol: 'http',host: 'chuchur.com', hash: { b: 1, c:2 } }


完整代码

  1. (function (win) {
  2.   var _$ = function (selector, context) {
  3.     /**
  4.      * 通常咱们定义一个 函数 var Fun = function(){}
  5.      * 然后定义一个 Fun.prototype.init = function(){}
  6.      * 那么咱们调用init 的时候 得先要实例化对象 var f = new Fun()
  7.      * 然后f.init()
  8.      * 这里就省去了 var $ = new $()
  9.      */
  10.     return new _$.prototype.Init(selector, context);
  11.   };
  12.   _$.prototype = {
  13.     //初始化$
  14.     Init: function (selector, context) {
  15.       this.elements = [];
  16.       /**
  17.        * 传入的类型是function 就执行ready事件,如果是document 就将document对象插入到this.elements
  18.        * 主要就是判断$(document).ready  和 $(function(){}) 这两种的ready事件的写法
  19.        */
  20.       if (typeof selector === "function") {
  21.         this.elements.push(document);
  22.         this.ready(selector);
  23.       } else {
  24.         var context = context || document;
  25.         var isDocument = (ele) =>
  26.           Object.prototype.toString.call(ele) == "[object HTMLDocument]" ||
  27.           "[object Document]";
  28.         if (isDocument(selector)) {
  29.           this.elements.push(selector);
  30.         } else {
  31.           /**
  32.            * 如果是字符串的话就查询该节点 $('.class') | $('#id')
  33.            */
  34.           if (context.querySelectorAll) {
  35.             var arr = context.querySelectorAll(selector);
  36.             for (var i = 0; i < arr.length; i++) {
  37.               this.elements.push(arr[i]);
  38.             }
  39.           }
  40.         }
  41.       }
  42.     },
  43.     //实现each
  44.     each: function (callback) {
  45.       if (this.elements.length > 0) {
  46.         for (var i = 0; i < this.elements.length; i++) {
  47.           callback.call(this, this.elements[i], i);
  48.         }
  49.       }
  50.     },
  51.     //实现ready
  52.     ready: function (callback) {
  53.       var isDocument = (ele) =>
  54.         Object.prototype.toString.call(ele) == "[object HTMLDocument]" ||
  55.         "[object Document]";
  56.       //如果已经取得了节点
  57.       if (isDocument(this.elements[0])) {
  58.         if (document.addEventListener) {
  59.           //判断火狐、谷歌
  60.           /**
  61.            * DOM树构建完成的时候就会执行DOMContentLoaded
  62.            * 页面上所有的DOM,样式表,脚本,图片,flash都已经加载完成了,才会触发window.onload
  63.            * 这也就是$(document).ready() 比 window.onload 执行早的原因
  64.            *
  65.            * arguments.callee 博客里面有一篇文章 js-递归里面专门讲到了,这里不再解释了
  66.            */
  67.           document.addEventListener(
  68.             "DOMContentLoaded",
  69.             function () {
  70.               document.removeEventListener(
  71.                 "DOMContentLoaded",
  72.                 arguments.callee,
  73.                 false
  74.               );
  75.               callback();
  76.             },
  77.             false
  78.           );
  79.         } else if (document.attachEvent) {
  80.           //判断IE
  81.           document.attachEvent("onreadystatechange", function () {
  82.             if (document.readyState == "complete") {
  83.               document.detachEvent("onreadystatechange", arguments.callee);
  84.               callback();
  85.             }
  86.           });
  87.         } else if (document.lastChild == document.body) {
  88.           //body已经加载完了,就直接回调了
  89.           callback();
  90.         }
  91.       }
  92.     },
  93.     //实现bind
  94.     bind: function (type, callback) {
  95.       if (document.addEventListener) {
  96.         //判断火狐、谷歌
  97.         this.each(function (item, i) {
  98.           item.addEventListener(type, callback, false);
  99.         });
  100.       } else if (document.attachEvent) {
  101.         //判断IE
  102.         this.each(function (item, i) {
  103.           item.attachEvent("on" + type, callback);
  104.         });
  105.       } else {
  106.         this.each(function (item, i) {
  107.           //其他浏览器 egg: item.onclick = function(){}
  108.           item["on" + type] = callback;
  109.         });
  110.       }
  111.     },
  112.   };
  113.   /**
  114.    * 让两个作用于不一样的对象共享一个方法,让他们的原型指向一直,即Init.prototype = _$.prototype
  115.    * 那么指向之后 就可以共享this.elements 属性了。
  116.    */
  117.   _$.prototype.Init.prototype = _$.prototype;
  118.  
  119.   var isObj = (o) => Object.prototype.toString().call(o) === "[object Object]";
  120.   $.fn.extend = function (obj) {
  121.     if (isObj(obj)) {
  122.       for (var i in obj) {
  123.         this[i] = obj; //注意这里的this指向是 $.prototype
  124.       }
  125.     }
  126.     //....这里是简写
  127.   };
  128.  
  129.   _$.extend = function (obj) {
  130.     if (isObj(obj)) {
  131.       for (var i in obj) {
  132.         this[i] = obj[i]; //注意这里的this指向是 $
  133.       }
  134.     }
  135.     //....这里是简写
  136.   };
  137.  
  138.   window.= _$;
  139. })(window || global);

【完】

TAG标签:
本文网址:https://www.zztuku.com/detail-9078.html
站长图库 - 你值得了解的JavaScript“继承之jquery”使用方法(代码详解)
申明:如有侵犯,请 联系我们 删除。

评论(0)条

您还没有登录,请 登录 后发表评论!

提示:请勿发布广告垃圾评论,否则封号处理!!

    编辑推荐

    CDR绘制活力城市/海报