jQuery Merge 是一個 jQuery 函數,它用于將兩個或多個對象合并為一個。該函數是一個非常實用的工具,使開發人員可以快速將不同來源的數據進行整合。
下面是 jQuery Merge 的源碼,我們來一步步解析:
jQuery.extend({
/**
* Merge the contents of two or more objects together into the first object.
* @param {Boolean} [deep] If true, the merge becomes recursive (aka. deep copy).
* @param {Object} target The object to extend. It will receive the new properties.
* @param {Object} object1 An object containing additional properties to merge in.
* @param {Object} objectN Additional objects containing properties to merge in.
* @returns {Object} The modified target object.
*/
merge: function( /*deep, */target /*, object1, objectN */ ) {
var options, name, src, copy, copyIsArray, clone,
target = arguments[0] || {},
i = 1,
length = arguments.length,
deep = false;
// Handle a deep copy situation
if ( typeof target === "boolean" ) {
deep = target;
// Skip the boolean and the target
target = arguments[ i ] || {};
i++;
}
// Handle case when target is a string or something (possible in deep copy)
if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
target = {};
}
// Extend jQuery itself if only one argument is passed
if ( i === length ) {
target = this;
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
if ( target === copy ) {
continue;
}
// Recurse if we're merging plain objects or arrays
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;
}
});
這段源碼的注釋已經很詳細了,簡單來說,這個函數接受任意數量的對象,把它們合并到一個新的對象中。如果多個對象中存在相同的屬性,后面的對象會覆蓋前面的對象中的屬性。
這個函數還支持深度合并,也就是說,如果合并的對象中存在對象嵌套的情況,它會遞歸合并這些對象。
在函數內部,首先會解析參數,判斷是否需要進行深度合并,以及要合并到哪個對象中。然后遍歷所有的參數對象,在每個對象中查找屬性,并與目標對象中的屬性進行合并。
如果屬性是一個對象或數組,則遞歸地進行合并。
// Recurse if we're merging plain objects or arrays
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;
}
最后,函數返回合并之后的對象。