jQuery设计原理-无new构建实例

作者 : 开心源码 本文共2957个字,预计阅读时间需要8分钟 发布时间: 2022-05-13 共157人阅读

jQuery无new构建实例

无new化构建

在jQuery中 $符号就是jQuery的别称

$()就是创立了jQuery的实例对象

实现

(function(root){    function jQuery() {        return new jQuery.prototype.init();    };    // 在jQuery的原型上定义init方法    jQuery.prototype = {        init: function() {        },        css: function() {            // 在jQuery原型上扩展的属性也会被共享到init的原型上        }    }    // 把jQuery的原型共享给init的原型    jQuery.prototype.init.prototype = jQuery.prototype;    // 设置全局变量$和jQuery    root.$ = root.jQuery = jQuery;})(this); // 把宿主对象window传进

共享原型设计

形容

如上, 在实现jQuery实例化的时候,我们直接调用$();

console.log($());

由于$()指向的是jQuery函数,所以相当于调用了jQuery函数;

 // 设置全局变量$和jQuery; // $和window.jQuery指向的都是jQuery函数    root.$ = root.jQuery = jQuery;

jQuery作为构造函数直接被调用效果和普通函数呗调用一样,

所以无法生成有效实例;

处理方案:

只能把jQuery函数的返回值设成构造函数的实例;

function jQuery() {        return new jQuery();};

但是这样做是不行的,很显著会造成死循环

所以jQuery采用的共享原型的设计模式, 即;

  • 在jQuery函数的prototype上定义了init方法

    // 在jQuery的原型上定义init方法  jQuery.prototype = {      init: function() {      }  }
  • 把jQuery的原型共享给init

     // 把jQuery的原型共享给init的原型  jQuery.prototype.init.prototype = jQuery.prototype;
  • 通过$()调用jQuery函数时返回一个init的实例

      function jQuery() {      return new jQuery.prototype.init();  };
  • 给jQuery的prototype扩展属性的时候,因为原型共享,

    所以init的原型上也会具备该扩展属性

      jQuery.prototype = {      init: function() {      },      css: function() {          // 在jQuery原型上扩展的属性也会被共享到init的原型上      }  }    console.log($());

123.png

以上就是jQuery无new实例化的实现

原型扩展设计见下图:

1122.png

extend函数源码解析

extend函数用法:

  //  给任意对象扩展  var obj1 = { a:1, b:2 };  var obj2 = { c: 3 };   var res = $.extend(obj1, obj2);  console.log(res); // ===> { a:1, b:2, c: 3 }  console.log(obj1); // ===> { a:1, b:2, c: 3 }        // 给$(jQuery)进行扩展  $.extend({      myMethod: function() {          console.log('myMethod1');      }  })  $.myMethod(); //  myMethod1;  // 给$(jQuery)的实例进行扩展  $.fn.extend({      myMethod: function() {          console.log('myMethod2');      }  })  $().myMethod(); //  myMethod2;

extend函数用于给对象进行扩展,给jQuery提供了插件机制

  • 可以给任意对象扩展
  • 也可以给jQuery自身扩展

注:

  //  $.fn指向的就是$.prototype  jQuery.fn = jQuery.prototype = {     // ......  }
  1. extend再jQuery中之所以既能通过$.extend调用,

又能通过$().extend调用是由于在源码内部中实现了
jQuery.fn.extend = jQuery.extend = function() { // ...... }

extend实现与分析

    // extend    jQuery.fn.extend = jQuery.extend = function() {                var target = arguments[0] || {};        //  target赋值为第一个参数,也就是要扩展的对象        var length = arguments.length;          //  获取参数的个数        var i = 1;          var deep = false;                                var options, name, copy, src, copyIsArray, clone;        if(typeof target === 'boolean') {       //   当传入第一个参数是boolean时            deep = target;                      //   把参数deep的值设置为target,即传入的第一个参数            target = arguments[1];              //   把target(需扩展的对象设置为第二个参数)            i = 2;                              //   i = 2,以便之后从第三个参数开始遍历        };                                                  if(typeof target !== 'object') {        //  验证传入的参数为obj            target = {};        };        if(length === i) {                      //  假如只有一个参数,则extend方法为jQuery内部的扩展            target = this;                      //  把target的引用设置为this,指向$或者者$()            i--;                       };                                          // 浅拷贝        for( ;i < length; i++) {                //  boolean参数和所需要扩展的对象的属性无需遍历            if((options = arguments[i]) !==null) {                for(name in options) {                    copy = options[name];                    src = target[name];                    // 假如需要深拷贝,并且options的属性对应的是对象或者数组时                    if(deep && (jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)))) {                        if(copyIsArray) {                                    copyIsArray = false;    //copyIsArray不重置会影响下一次循环的判断;                            clone = src && jQuery.isArray(src) ? src : [];                        } else {                            clone = src && jQuery.isPlainObject(src) ? src : {};                        }                        target[name] = jQuery.extend(deep, clone, copy);                    } else if(copy !== undefined) {                        target[name] = copy;                    };                };            };        };        return target;    }        jQuery.extend({        isPlainObject: function(obj) {  //  判断传入参数的数据类型能否是obj            return toString.call(obj) === '[object Object]'        },        isArray: function(arr) {        //  判断传入参数的数据类型能否是数组            return toString.call(arr) === '[object Array]'        }    });

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » jQuery设计原理-无new构建实例

发表回复