这是一个扩展合并函数
合并两个或更多对象的属性到第一个对象中,jQuery 后续的大部分功能都通过该函数扩展
1.合并两个普通对象
//给两个普通对象合并属性
var obj1={name:'Tom',age:22};
var obj2={name:'Jack',height:180};
console.log($.extend(obj1,obj2)); //Object {name: "Jack", age: 22, height: 180}
$.extend({hehe:function(){alert('hehe');}});
$.hehe(); //alert('hehe')
var src, copyIsArray, copy, name, options, clone,
target = arguments[0] || {},
i = 1,
length = arguments.length,
deep = false;
首先是定义了一组变量,因为参数个数不确定所以就直接调用arguments对象访问传递的参数
‰ ‰ 变量 options:指向某个源对象。
‰ ‰ 变量 name:表示某个源对象的某个属性名。
‰ ‰ 变量 src:表示目标对象的某个属性的原始值。
‰ ‰ 变量 copy:表示某个源对象的某个属性的值。
‰ ‰ 变量 copyIsArray:指示变量 copy 是否是数组。
‰ ‰ 变量 clone:表示深度复制时原始值的修正值。
‰ ‰ 变量 target:指向目标对象。
‰ ‰ 变量 i:表示源对象的起始下标。
‰ ‰ 变量 length:表示参数的个数,用于修正变量 target。
‰ ‰ 变量 deep:指示是否执行深度复制,默认为 false。
if (typeof target === "boolean") {
deep = target;
target = arguments[1] || {};
i = 2;
}
判断是不是深拷贝,如果是i则从2开始,target也就是第二个参数
if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
target = {};
}
这里对 target 进行了进一步处理,即第一个参数是字符串或者其他
if (length === i) {
target = this;
--i;
}
length等于表示没有目标对象,即给jquery对象添加静态方法
for (; i < length; i++) {
// 将每个源的属性全部复制到 target 上
if ((options = arguments[i]) != null) {
for (name in options) {
// src 是源(即本身)的值
// copy 是即将要复制过去的值
src = target[name];
copy = options[name];
// Prevent never-ending loop
// 防止有环,例如 extend(true, target, {'target':target});
if (target === copy) {
continue;
}
// 这里是递归调用,最终都会到下面的 else if 分支
// jQuery.isPlainObject 用于测试是否为纯粹的对象
// 纯粹的对象指的是 通过 "{}" 或者 "new Object" 创建的
// 如果是深复制
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 : {};
}
// 递归
target[name] = jQuery.extend(deep, clone, copy);
// 最终都会到这条分支
// 简单的值覆盖
} else if (copy !== undefined) {
target[name] = copy;
}
}
}
}