$.extend()常用的几种方法 参考http://www.cnblogs.com/zikai/p/5074686.html (先看这个更容易理解 $.extend()设计原理)
接下来详细介绍它的实现
jQuery.extend = jQuery.fn.extend = function() {
var options, name, src, copy, copyIsArray, clone,
target = arguments[ 0 ] || {},
i = 1,
length = arguments.length,
deep = false; //默认是无需深度遍历
if ( typeof target === "boolean" ) { //判断第一参数是否为boolean,表示是否要深度遍历
deep = target;
target = arguments[ i ] || {};
i++;
}
if ( typeof target !== "object" && !jQuery.isFunction( target ) ) { //遍历的对象必须为object或者function
target = {};
}
if ( i === length ) { //判断是否是自身扩展,自身扩展就是所有遍历的方法属性都添加到$.fn,不是自身扩展的时候所有
target = this; //的对象都扩展到第一个非boolean的参数中(结合上面的链接理解起来更轻松)
i--;
}
for ( ; i < length; i++ ) { //遍历传入的所有参数,进行相应的对象扩展
if ( ( options = arguments[ i ] ) != null ) {
//遍历一个参数的所有属性、方法,非深度扩展时直接覆盖前面对象,深度扩展时递归进入对象里面以
//基本类型数据覆盖前面数据
for ( name in options )
{
src = target[ name ];
copy = options[ name ];
if ( target === copy ) { //防止无限循环
continue;
}
if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
( copyIsArray = Array.isArray( copy ) ) ) ) {
if ( copyIsArray ) {
copyIsArray = false;
clone = src && Array.isArray( src ) ? src : [];
} else {
clone = src && jQuery.isPlainObject( src ) ? src : {};
}
target[ name ] = jQuery.extend( deep, clone, copy ); //递归的方式深度遍历对象、数组
} else if ( copy !== undefined ) { // 无需深度扩展或者已经是基本类型数据,就直接扩展
target[ name ] = copy;
}
}
}
}
return target;
};
注意:这个方法表示 jQuery.extend 与jQuery.fn.extend 指向同一个引用,而里面的this 根据调用者改变,指向jQuery.extend 或者jQuery.fn
eg : $.extend(dest,src1,src2,src3...); 把src1后面的对象全部扩展到dest里面,修改了dest原对象,最后返回的是扩展之后的dest
eg:$.extend({},src1,src2,src3...) 添加一个空对象,所有参数扩展到{} 里面,保留了原对象eg: $.fn.extend({src1,src2..}) 把src1...扩展到$.fn里面,而$.fn.init.prototype = $.fn,这样就扩展了$实例化方法
PS:
1、当我们需要扩展$()实例化方法的时候就需要用到 $.fn.extend, 所有的jquery插件都是通过这个入口扩展它的实例方法
2、$.extend({})表示扩展的方法添加到$中,通过 ' $. ' 引用, $.fn.extend({}),扩展到$.fn里面,通过 '$("节点").' 引用