// 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;
};
