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

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]'
        }
    });

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350