$.extend中探索深拷贝和浅拷贝

网上这方面的教程比较多,由于上次看了篇错误的教程搞得我迷糊;特意写下这篇笔记,若文中有错误之处,忘路过的朋友及时指出,不想祸害其他朋友了;

首先说明下:深拷贝(深复制)和浅拷贝(浅复制),特地说明怕有人以为又是不同的概念,其实是一样的;

1.浅拷贝(浅复制):一句话概况就是多个对象之间对Objectl类型数据的备份,其实只是备份存储在栈内存中的地址;本质上还是指向同一个堆内存中的数据;

 

实例代码如下:

 

以上代码可知:当你改变obj对象的name属性,通过浅拷贝过去的obj1对象的name属性也会相应的改变;这种结果在跟后台做交互的时候会很出现各种各样的毛病;

2.深拷贝(深复制):深拷贝不再局限于对于对象内存地址的引用了,它是完全复制了一个对象,把被复制的对象的遍历一遍,然后赋值给新的对象并返回;

3.jQuery框架中的$.extend()方法就是这么实现的;不过jQuery的深拷贝还分为两部分:普通深拷贝和递归(深度)深拷贝(我乱起的名字,不喜勿喷);我们就根据$.extend()方法来分析深拷贝;

先贴上jQuery源码:(只有$.extend方法的那一段)=>$.extend(boolean,obj1,obj2);

jQuery.extend = jQuery.fn.extend = function() {
	var options, name, src, copy, copyIsArray, clone,
		target = arguments[ 0 ] || {},	//获取第一个参数并赋给变量target
		i = 1,
		length = arguments.length,	//获取参数的长度
		deep = false;	//deep变量决定是否进行普通拷贝还是递归拷贝
	// Handle a deep copy situation
	if ( typeof target === "boolean" ) { //判断变量target是否是boolean类型
		deep = target;
		// Skip the boolean and the target
		target = arguments[ i ] || {};	
		i++;
	}
	// Handle case when target is a string or something (possible in deep copy)
	if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
		target = {};
	}
	//如果函数参数只有一个,那么target变量则引用jQuery实例化的对象;
	if ( i === length ) {
		target = this;
		i--;
	}
	for ( ; i < length; i++ ) {//遍历所传参
		if ( ( options = arguments[ i ] ) != null ) {//并将参数复值给变量options
			for ( name in options ) {
				src = target[ name ];
				copy = options[ name ];
				//判断目标对象和需要被复制的对象是否一致,一致就跳过进行下一次循环
				//目标对象target;被复制的对象copy
				if ( target === copy ) {
					continue;
				}
				// 如果deep是true,copy是对象或者是数组则进行递归(也就是在函数里面调用自身)
				//说明这里只是根据被复制的对象来决定是否进行递归,否则直接覆盖,不进行深度深拷贝
				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 : {};
					}
					// Never move original objects, clone them
					target[ name ] = jQuery.extend( deep, clone, copy );
				// Don't bring in undefined values
				} else if ( copy !== undefined ) {
					target[ name ] = copy;
				}
			}
		}
	}
	// Return the modified object
	return target;
};

从上面源码分析可知,jQuery中的extend()方法不过deep是否是true还是false,它都是进行深拷贝(深复制)的;同时extend方法进行深拷贝的条件还有需要被拷贝的对象,也就是extend()方法中的copy变量是否是对象还是数组;如果copy对象不是一个引用类型(对象或数组),比如字符串:则仍会将字符串作为类数组被for in进行循环并分解给目标对象target;并且不管是普通深拷贝还是递归深拷贝,最终返回的是被处理过的目标对象target;

代码如下:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值