1. 程式人生 > >jQuery.extend() 源碼分析

jQuery.extend() 源碼分析

源碼分析 參數 cti 因此 ID 功能 遞歸 ini 深克隆

jQuery.extend() 方法

  1. 可以合並對象
  2. 深拷貝與淺拷貝

技術分享圖片

源碼分析:

概述: 1. 首先定義變量

      options:保存每次循環遍歷的arguments[i] ,

      name: 保存循環遍歷對象的key值

      src:保存目標對象target的屬性

      copy: 保存合並對象的屬性

      copyIsArray: 如果copy是數組,用copyIsArray保存

      clone:如果目標對象是數組,用clone保存。

      target:目標對象

      deep: boolean值,判斷是否是深拷貝

    2. 然後判斷是否是深拷貝,如果是deep值變為target,i的值變為2,跳過前兩個參數。

    3. 判斷target是不是一個對象或者函數,如果都不是,就把target變為一個空對象

    4. 判斷是否只有一個參數的情況

    5. 遍歷需要被擴展target的參數,判斷deep是否是true,如果是,就利用遞歸開始深克隆,如果不是就淺克隆

    6. 如果是淺克隆,就直接把copy的值賦給target[name]。

註意:不支持第一個參數寫false,如果是淺拷貝就不要寫。

 1 // extend方法為jQuery對象和init對象的prototype擴展方法
 2 // 同時具有獨立的擴展普通對象的功能
 3 jQuery.extend = jQuery.fn.extend = function
() { 4 /* 5   *target被擴展的對象 6   *length參數的數量 7   *deep是否深度操作 8   */ 9 var options, 10 name, 11 src, 12 copy, 13 copyIsArray, 14 clone, 15 target = arguments[0] || {}, 16 i = 1, 17 length = arguments.length, 18 deep = false; 19 // target為第一個參數,如果第一個參數是Boolean類型的值,則把target賦值給deep
20 // deep表示是否進行深層面的復制,當為true時,進行深度復制,否則只進行第一層擴展 21 // 然後把第二個參數賦值給target 22 if (typeof target === ‘boolean‘) { 23 deep = target; 24 target = arguments[1] || {}; 25 // 將i賦值為2,跳過前兩個參數 26 i = 2; 27 } 28 // target既不是對象也不是函數則把target設置為空對象。 29 if (typeof target !== ‘object‘ && !jQuery.isFunction(target)) { 30 target = {}; 31 } 32 // 如果只有一個參數,則把jQuery對象賦值給target,即擴展到jQuery對象上 33 // extend(true, {}); 34 // extend(obj); 35 if (length === i) { 36 // this ==> jQuery/jQuery.fn 37 target = this; 38 // 如果i=2, --i是為了讓循環從1開始,如果i=1, --i是為了讓循環從0開始 39 --i; 40 } 41 // 開始遍歷需要被擴展到target上的參數 42 for (; i < length; i++) { 43 // 處理第i個被擴展的對象,即除去deep和target之外的對象 44 if ((options = arguments[i]) != null) { 45 // 遍歷第i個對象的所有可遍歷的屬性 46 for (name in options) { 47 // 用src保存目標對象的屬性 48 src = target[name]; 49 // 用copy保存合並對象的屬性 50 copy = options[name]; 51 // 如果兩個屬性相等,就不用合並了 52 if (target === copy) { 53 continue; 54 } 55 // 當用戶想要深度操作時,遞歸合並 56 // copy是純對象或者是數組 57 if ( 58 deep && 59 copy && 60 (jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy))) 61 ) { 62 // 如果是數組 63 if (copyIsArray) { 64 // 將copyIsArray重新設置為false,為下次遍歷做準備。 65 copyIsArray = false; 66 // 判斷被擴展的對象中src是不是數組 67 clone = src && jQuery.isArray(src) ? src : []; 68 } else { 69 // 判斷被擴展的對象中src是不是純對象 70 clone = src && jQuery.isPlainObject(src) ? src : {}; 71 } 72 // 遞歸調用extend方法,繼續進行深度遍歷 73 target[name] = jQuery.extend(deep, clone, copy); 74 } 75 // 如果不需要深度復制,則直接把copy(第i個被擴展對象中被遍歷的那個鍵的值) 76 else if (copy !== undefined) { 77 target[name] = copy; 78 } 79 } 80 } 81 } 82 // 原對象被改變,因此如果不想改變原對象,target可傳入{} 83 return target; 84 };

示例:

技術分享圖片

如果要合並以上兩個對象

需要一下6步

技術分享圖片

jQuery.extend() 源碼分析