这次主要分析的是JQuery中的extend函数,extend函数在JQuery中占的作用十分明显,在后期JQuery方法的添加上,基本是使用这个函数来添加到JQuery对象和prototype上的。这个函数另一个重要作用是在框架开发的时候使用,可以直接对JQuery增加新的功能。
说明了重要性之后,就开始讲解函数了(函数的使用方法就不讲了,具体可以看官方文档:http://api.jquery.com/jQuery.extend/#jQuery-extend-target-object1-objectN)。首先是函数的位置:
jQuery.extend = jQuery.fn.extend = function() { //some code }
可以看到,extend函数直接加在了jQuery对象和prototype上(jQuery.fn =jQuery.prototype),这是因为函数内部存在判断,如果要拓展的target缺失的话,就会直接用this。这样就可以方便开发者们自己确定函数放的位置了。
接下来就是具体函数内容分析了,下面这一段是先定义一系列需要的变量,其中target是要扩展的对象,deep是指是否深度复制,i=1是因为target已经默认指向了arguments[0]了,再接下来读取参数的时候,arguments[i]就可以直接从第二项开始了。:
var src, copyIsArray, copy, name, options, clone, target = arguments[0] || {}, i = 1, length = arguments.length, deep = false; // 当第一参数是布尔值时,就让target等于第二个参数,而第一个参数确定为是否深度复制 if ( typeof target === "boolean" ) { deep = target; // target 往后移动一位,i自加 target = arguments[ i ] || {}; i++; } // 处理当target为字符串或其他的时候 if ( typeof target !== "object" && !jQuery.isFunction(target) ) { target = {}; } // 当只有一个参数或者只有是否深度复制和被复制的变量时,将target指向this(一般为jQuery) if ( i === length ) { target = this; i--; }
通过以上这些代码的处理,就可以解决了deep和target的赋值问题,接下来就是通过循环来将值复制到target中。
//支持添加多个被添加变量 for ( ; i < length; i++ ) { // 只处理值不为undefined和null的情况 if ( (options = arguments[ i ]) != null ) { for ( name in options ) { src = target[ name ]; copy = options[ name ]; // 当copy指向target时,有可能导致无限循环,遇到这种情况直接跳过 if ( target === copy ) { continue; } // 当确定是深度复制后,用递归进行 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { //判断copy的类型,若target下该项没有的时候,建立相同类型的变量 if ( copyIsArray ) { copyIsArray = false; clone = src && jQuery.isArray(src) ? src : []; } else { clone = src && jQuery.isPlainObject(src) ? src : {}; } // 进行深度复制,同时不改变copy target[ name ] = jQuery.extend( deep, clone, copy ); // 浅复制,直接等于即可 } else if ( copy !== undefined ) { target[ name ] = copy; } } } } // 返回完成的target return target;