Home » Code » 菜鸟学习jQuery源码Part3——扩展方法extend()

菜鸟学习jQuery源码Part3——扩展方法extend()

定义了基本的原型属性方法,开始定义扩展方法extend()。jQuery自身的静态方法和其他原型方法都是通过这个方法来扩展的,而且这个方法在jQuery自身及jQuery对象上都存在,使用的同一套代码。

jQuery.extend = jQuery.fn.extend = function() {
	var options, name, src, copy, copyIsArray, clone,
	//一个实参,一个实参中某key,目标中一项,待合并的项,待合并项是否数组,克隆项
		target = arguments[0] || {},//假定参数1是目标,后边的合并到目标中来
		i = 1,//参数1(游标0)是目标,从参数2(游标1)开始遍历
		length = arguments.length,//参数个数,用的“<”,不到边际
		deep = false;//默认不是深拷贝,是浅拷贝

	// Handle a deep copy situation,处理深拷贝
	if ( typeof target === "boolean" ) {//参数1是布尔类型
		deep = target;//是否深拷贝由参数1决定
		target = arguments[1] || {};//目标变为参数2
		// skip the boolean and the target,跳过布尔值及目标
		i = 2;//从参数3开始遍历
	}

	// 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
	//只有一个参数,是扩展jQuery自身,添加静态方法,内部使用
	if ( length === i ) {
		target = this;//目标变为jQuery
		--i;//i减1,变为0,0<1才有一次循环,否则进不了for
	}

	for ( ; i < length; i++ ) {
		// Only deal with non-null/undefined values,只处理不为null不为undefined的值
		if ( (options = arguments[ i ]) != null ) {
			// Extend the base object,扩展基础对象,也就是目标
			for ( name in options ) {//遍历一个实参(也就是后边的,都合并到目标上去)
				src = target[ name ];//该key在目标中的值
				copy = options[ name ];//后边实参将要合并到目标中的值

				// Prevent never-ending loop,
				/*防止无限循环,目标跟将要合并到目标的值相等时会出现,如
				*var a = {'a': 1};
				*var b = $.extend(a, {0: a});
				*/
				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;//重置为默认的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 );//递归调用,将待合并项copy合并到克隆项上,添加到目标上。

				// Don't bring in undefined values,跳过undefined
				} else if ( copy !== undefined ) {
					target[ name ] = copy;//简单值类型的数据直接添加到目标上即可
				}
			}
		}
	}

	// Return the modified object
	return target;
};

其实这个方法一般当静态方法使用的多,一是合并参数,在插件拼写时候经常用,二是给jQuery添加静态方法。

有了这个利器,从349行开始就为jQuery自身扩展了一堆静态属性、方法。

expando

一个页面上唯一的字符串,由”jQuery”+版本号+随机数组成。

noConflict()

防止$、jQuery覆盖已有变量的方法,将jQuery转移为其他变量名。jQuery这个匿名自执行函数的最后会将$及jQuery附到window的属性上,如果之前就定义有,就给覆盖了。不传参数时,还原$。传true参数时,连同jQuery也不占用。

noConflict: function( deep ) {
	if ( window.$ === jQuery ) {//自执行函数完后,这个肯定为真
		window.$ = _$;//还原为之前定义的$值
	}

	if ( deep && window.jQuery === jQuery ) {
		window.jQuery = _jQuery;//同样的将jQuery也还原
	}

	return jQuery;//返回当前作用域的jQuery,外边定义一个新的变量名来接收,不占用$、jQuery
},

Leave a Reply

Your email address will not be published. Required fields are marked *

*

Time limit is exhausted. Please reload CAPTCHA.