// 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;html
// 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 = {};
}post
// 若是隻有一個參數,則把jQuery對象賦值給target,即擴展到jQuery對象上
if ( length === i ) {
target = this;this
// i減1,指向被擴展對象
--i;
}prototype
// 開始遍歷須要被擴展到target上的參數htm
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;
}blog
// 當用戶想要深度操做時,遞歸合併
// 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;
};