概述
本文详细分析jquery-1.11.1.js源码文件行数:174~584;
代码简介:定义了extend()函数,并用其扩展了一些常用的工具函数;
下文进行详细代码分析。
extend():jQuery的继承方法
// 同时被jQuery以及jQuery.fn即原型引用,便于后面扩展各自的函数
// 扩展进jQuery的函数,可通过jQuery这个命名空间去调用,称之为工具函数,是jQuery较底层的实现,内部很多其他函数都调用了工具函数
// 扩展进jQuery.fn的函数,是所有JQ对象的公用函数
jQuery.extend = jQuery.fn.extend = function() {
var src, copyIsArray, copy, name, options, clone,
// 初始化要扩展的target是第一个参数,如果arguments[0]是false,即表示浅拷贝,则target直接设置成新对象
target = arguments[0] || {},
i = 1,
length = arguments.length,
// 默认是浅拷贝
deep = false;
// 从前面初始化可以看出,如果成立则肯定为深度拷贝,则传给deep
if ( typeof target === "boolean" ) {
deep = target;
// 再将target指向第二个参数
target = arguments[ i ] || {};
i++;
}
// 兼容target不是对象或函数的场景
if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
target = {};
}
// 由前面的代码可以看出,i永远领先1的,如果i === length成立,则表示设置了target = arguments[i--]||{}之后,就已经没有其他参数可以用于扩展了
// 则target = this;把需要扩展的对象设置成调用者本身,而顺理成章arguments[i--]成为被扩展的对象
if ( i === length ) {
target = this;
i--;
}
// 以上的代码都是对arguments的不同情况进行兼容,确定需要扩展的对象target,以及deep,还有i的值
// i的值用于后面遍历arguments,arguments[i]以上的参数就是被扩展的对象了
for ( ; i < length; i++ ) {
// options指向arguments[ i ]并进行空判断
if ( (options = arguments[ i ]) != null ) {
// 循环遍历options每一个可扩展属性
for ( name in options ) {
src = target[ name ];
copy = options[ name ];
// 防止循环引用自身
if ( target === copy ) {
continue;
}
// 处理深度拷贝场景,需要判断copy是否能拷贝,jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) 满足即可
if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
if ( copyIsArray ) {
// copyIsArray = false;这行我个人觉得是多余的,后面没有使用copyIsArray的地方了
copyIsArray = false;
// 如果src不为空且是类数组结构,则直接将src作为扩展对象进入下一轮递归,原内容会被替换掉
clone = src && jQuery.isArray(src) ? src : [];
} else {
// 同上如果src不为空且是纯粹的对象({}或new Object()建立的),则直接将src作为扩展对象进入下一轮递归,原内容会被替换掉
clone = src && jQuery.isPlainObject(src) ? src : {};
}
// 进入递归
target[ name ] = jQuery.extend( deep, clone, copy );
// 被扩展属性不为空则扩展进target[ name ]
} else if ( copy !== undefined ) {
target[ name ] &