jQuery.extend()源碼解讀


// extend方法為jQuery對象和init對象的prototype擴展方法
// 同時具有獨立的擴展普通對象的功能
jQuery.extend = jQuery.fn.extend = function() {
  /*
  *target被擴展的對象
  *length參數的數量
  *deep是否深度操作
  */
  var options, name, src, copy, copyIsArray, clone,
    target = arguments[0] || {},
    i = 1,
    length = arguments.length,
    deep = false;

  // target為第一個參數,如果第一個參數是Boolean類型的值,則把target賦值給deep
  // deep表示是否進行深層面的復制,當為true時,進行深度復制,否則只進行第一層擴展
  // 然后把第二個參數賦值給target
  if ( typeof target === "boolean" ) {
    deep = target;
    target = arguments[1] || {};

    // 將i賦值為2,跳過前兩個參數
    i = 2;
  }

  // target既不是對象也不是函數則把target設置為空對象。
  if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
    target = {};
  }

  // 如果只有一個參數,則把jQuery對象賦值給target,即擴展到jQuery對象上
  if ( length === i ) {
    target = this;

    // i減1,指向被擴展對象
    --i;
  }

  // 開始遍歷需要被擴展到target上的參數

  for ( ; i < length; i++ ) {
    // 處理第i個被擴展的對象,即除去deep和target之外的對象
    if ( (options = arguments[ i ]) != null ) {
      // 遍歷第i個對象的所有可遍歷的屬性
      for ( name in options ) {
        // 根據被擴展對象的鍵獲得目標對象相應值,並賦值給src
        src = target[ name ];
        // 得到被擴展對象的值
        copy = options[ name ];

        // 這里為什么是比較target和copy?不應該是比較src和copy嗎?
        if ( target === copy ) {
          continue;
        }

        // 當用戶想要深度操作時,遞歸合並
        // copy是純對象或者是數組
        if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
          // 如果是數組
          if ( copyIsArray ) {
            // 將copyIsArray重新設置為false,為下次遍歷做准備。
            copyIsArray = false;
            // 判斷被擴展的對象中src是不是數組
            clone = src && jQuery.isArray(src) ? src : [];
          } else { 
            // 判斷被擴展的對象中src是不是純對象
            clone = src && jQuery.isPlainObject(src) ? src : {};
          }

          // 遞歸調用extend方法,繼續進行深度遍歷
          target[ name ] = jQuery.extend( deep, clone, copy );

        // 如果不需要深度復制,則直接把copy(第i個被擴展對象中被遍歷的那個鍵的值)
        } else if ( copy !== undefined ) {
          target[ name ] = copy;
        }
      }
    }
  }

  // 原對象被改變,因此如果不想改變原對象,target可傳入{}
  return target;
};


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM