// 为与源码的下标对应上,我们把第一个参数称为`第0个参数`,依次类推
jQuery.extend_deepclone = jQuery.fn.extend = function () {
var options,
name,
src,
copy,
copyIsArray,
clone,
target = arguments[0] || {}, // 默认第0个参数为目标参数
i = 1, // i表示从第几个参数开始将目标参数与其进行合并,默认从第1个参数开始向第0个参数进行合并
length = arguments.length,
deep = false; // 默认为浅拷贝
// 判断第0个参数的类型,若第0个参数是boolean类型,则获取其为true还是false
// 同时将第1个参数作为目标参数,i从当前目标参数的下一个
// Handle a deep copy situation
if (typeof target === "boolean") {
deep = target;
// Skip the boolean and the target
// 如果第一个参数是Boolean类型
target = arguments[i] || {};
i++;
}
// 判断目标参数的类型,若目标参数既不是object类型,也不是function类型,则为目标参数重新赋值空对象
// Handle case when target is a string or something (possible in deep copy)
if (typeof target !== "object" && !jQuery.isFunction(target)) {
target = {};
}
// 若目标参数后面没有参数了,如$.extend({_name:'wenzi'}), $.extend(true, {_name:'wenzi'})
// 则目标参数即为jQuery本身,而target表示的参数不再为目标参数
// Extend jQuery itself if only one argument is passed
if (i === length) {
target = this;
i--;
}
// 从第i个参数开始遍历
for (; i < length; i++) {
// 获取第i个参数,且该参数不为null和undefind,在js中null和undefined,如果不区分类型,是相等的,null==undefined为true,
// 因此可以用null来同时过滤掉null和undefind
// 比如$.extend(target, {}, null);中的第2个参数null是不参与合并的
// Only deal with non-null/undefined values
if ((options = arguments[i]) != null) {
// 使用for~in获取该参数中所有可枚举的属性
// Extend the base object
for (name in options) {
src = target[name]; // 目标参数中name字段的值
copy = options[name]; // 当前参数中name字段的值,有可能是值,Object,Array
// 若参数中属性的值就是目标参数,停止赋值,进行下一个字段的赋值
// 这是为了防止无限的循环嵌套,我们把这个称为,在下面进行比较详细的讲解
// Prevent never-ending loop
if (target === copy) {
continue;
}
// 若deep为true,且当前参数中name字段的值存在且为object类型或Array类型,则进行深度赋值
// Recurse if we're merging plain objects or arrays
// jQuery.isPlainObject()返回值为Boolean类型,如果指定的参数是纯粹的对象,则返回true,否则返回false
if (deep && copy && (jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)))) {
// 若当前参数中name字段的值为Array类型
// 判断目标参数中name字段的值是否存在,若存在则使用原来的,否则进行初始化
if (copyIsArray) {
//被复制的属性的值类型为Array
copyIsArray = false;
//判断该字段在target对象是否存在,存在且为Array,则直接使用原对象,否则创建空的Array
clone = src && jQuery.isArray(src) ? src : [];
} else {
// 被复制的属性的值得类型为Object
//判断该字段在target对象是否存在,若存在且为Object则直接使用,否则创建空的Object
clone = src && jQuery.isPlainObject(src) ? src : {};
}
// 递归处理,此处为2.2
// Never move original objects, clone them
target[name] = jQuery.extend(deep, clone, copy);
// deep为false,则表示浅度拷贝,直接进行赋值
// Don't bring in undefined values
} else if (copy !== undefined) {
// 若copy是简单的类型且存在值,则直接进行赋值
// 若原对象存在name属性,则直接覆盖掉;若不存在,则创建新的属性
target[name] = copy;
}
}
}
}
// 返回修改后的目标参数
// Return the modified object
return target;
};
调用示例:
var columns = [];
columns.push({ field: 'ck', title: '', width: 50, checkbox: true });
columns.push({ field: 'xxx', title: '年度', width: 60, sortable: false, align: 'center', halign: 'center' });
var columnsxx = [];
$.extend_deepclone(columnsxx, columns);