JQuery_2.1.0_日記 4.29 $.extend

     因爲在JQuery一切皆JQuery,所以JQuery沒有EXT那麼恐怖的繼承體系,比起EXT的Ext.extends(),$.extend()函數還是很好理解的,只是把一個對象的屬性和方法添加到目標對象上.剛出生的JQuery是很弱小的,JQuery源碼後面和我們自己擴展都是通過$.extend()函數.
     
     Test_Html
     <body>
     <div id= "div1">div1</div ><div id= "div2">div2</div >
     <span id= "span1">span1</span ><span id= "span2">span2</span ><span id="span3" >span3 </span>
   </body>

   Test_Script
   $.extend(target, src);
   target.show();//function[native object]說明this是javascript內建對象構造函數

   $.extend(src);
   $.show();//function[native object]說明this是javascript內建對象構造函數,JQuery = function(){};

   $.fn.extend(src);
   $('div').show(); //function(selector, context)

   可以看到想擴展JQuery的靜態方法和屬性就$.extend,想擴展JQuery對象就用$.fn.extend,當然也可以擴展自己的簡單js對象.

   再看$.extend()源碼之前,先看一個深克隆和淺克隆的例子.
     
   淺克隆
   var target = {};
   var src = {copy:{name:'原始數據' }};
              
              
   $.extend(target, src);
   target.copy.name = '覆蓋數據' ;
   alert(src.copy.name); //覆蓋數

   深克隆
   var target = {};
   var src = {copy:{name:'原始數據' }};
              
              
   $.extend(true, target, src);
   target.copy.name = '覆蓋數據' ;
   alert(src.copy.name); //原始數據



   $.extend源碼
   
jQuery.extend = jQuery.fn.extend = function() {
        var options, name, src, copy, copyIsArray, clone,
              target = arguments[0] || {},
              i = 1,
              length = arguments.length,
              deep = false ;

        // Handle a deep copy situation
        //如果第一個參數是boolean類型
        //修正參數,將第二個參數作爲target
        if ( typeof target === "boolean" ) {
              deep = target;

               // skip the boolean and the target
              target = arguments[ i ] || {};
               //i++是爲了後續 i === length的判斷
              i++;
       }

        // Handle case when target is a string or something (possible in deep copy)
        //如果目標既不是對象也不是方法(例如給基本類型擴展屬性方法和屬性不會報錯但是是無用的),修正target爲 js對象
        if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
              target = {};
       }

        // extend jQuery itself if only one argument is passed
        //如果只有一個參數,修正對象爲JQuery函數或JQuery對象
        if ( i === length ) {
              target = this ;
               //修正target所在位置,後面的都是要添加給target的對象
              i--;
       }

        for ( ; i < length; i++ ) {
               // Only deal with non-null/undefined values
               if ( (options = arguments[ i ]) != null ) {
                      // Extend the base object
                      for ( name in options ) {
                           src = target[ name ];
                           copy = options[ name ];

                            // Prevent never-ending loop
                            //如果target和copy是同一個對象,略過,防止自己的屬性引用了本身對象導致的循環引用,以致GC無法回收
                            if ( target === copy ) {
                                   continue ;
                           }

                            // Recurse if we're merging plain objects or arrays
                            //如果是deep爲true,並且要添加給target的copy爲對象獲數組
                            if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
                                   if ( copyIsArray ) {
                                         copyIsArray = false ;
                                         clone = src && jQuery.isArray(src) ? src : [];

                                  } else {
                                         clone = src && jQuery.isPlainObject(src) ? src : {};
                                  }
                     
                                   // Never move original objects, clone them
                                   //很巧妙 ,用一個遞歸,實現引用對象的深克隆,遞歸的返回條件是屬性石基本類型,基本類型都是深克隆
                                  target[ name ] = jQuery.extend( deep, clone, copy );

                            // Don't bring in undefined values
                           } else if ( copy !== undefined ) {
                                   //淺克隆
                                  target[ name ] = copy;
                           }
                     }
              }
       }

        // Return the modified object
        return target;
};
   

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章