浅拷贝深拷贝之jQuery中的$.extend分析

        jQuery中的$.extend浅拷贝,拷贝对象A时,对象B将拷贝A的所有字段,如果字段是内存地址,B将拷贝地址,若果字段是基元类型,B将复制其值。它的缺点是如果你改变了对象B所指向的内存地址,你同时也改变了对象A指向这个地址的字段。

        jQuery中的$.extend深拷贝,这种方式会完全拷贝所有数据,优点是B与A不会相互依赖(A,B完全脱离关联), 缺点是拷贝的速度更慢,代价更大。

一.$.extend浅拷贝

        $.extend浅拷贝实例一,$.extend(a,b)用法,$.extend浅拷贝拷贝对象A时,对象B将拷贝A的所有字段,如果字段是内存地址,B将拷贝地址,若果字段是基元类型,B将复制其值。

<html>
<head>
</head>
	<meta charset="GBK">
	<title>StudyDemo01</title>
	<script type="text/javascript" src="jquery-1.8.3.js"></script>
	<script type="text/javascript">
		$(document).ready(function() {
			var a = {
				name : 'zhangshan',
				age : 28,
				company : {
					name : '腾讯',
					address : '深圳',
					size : 10000
				}
			};
			var b = {
				name : 'lisi',
				age : 30,
				company : {
					name : '阿里巴巴',
					address : '杭州'
				},
				stature : '172cm'
			};
			var c = $.extend(a,b);
			console.log('a:' + JSON.stringify(a));
			console.log('b:' + JSON.stringify(b));
			console.log('c:' + JSON.stringify(c));
		});
	</script>
<body>
</body>
</html>

        运行结果:

a:{"name":"lisi","age":30,"company":{"name":"阿里巴巴","address":"杭州"},"stature":"172cm"}
b:{"name":"lisi","age":30,"company":{"name":"阿里巴巴","address":"杭州"},"stature":"172cm"}
c:{"name":"lisi","age":30,"company":{"name":"阿里巴巴","address":"杭州"},"stature":"172cm"}

        $.extend浅拷贝实例二,$.extend(a,b)用法,如果你改变了对象B所指向的内存地址,你同时也改变了对象A指向这个地址的字段。

<html>
<head>
</head>
	<meta charset="GBK">
	<title>StudyDemo02</title>
	<script type="text/javascript" src="jquery-1.8.3.js"></script>
	<script type="text/javascript">
		$(document).ready(function() {
			var a = {
				name : 'zhangshan',
				age : 28,
				company : {
					name : '腾讯',
					address : '深圳',
					size : 10000
				}
			};
			var b = {
				name : 'lisi',
				age : 30,
				company : {
					name : '阿里巴巴',
					address : '杭州'
				},
				stature : '172cm'
			};
			var c = $.extend(a,b);
			b.name = 'test';
			b.company.address = '北京';
			console.log('a:' + JSON.stringify(a));
			console.log('b:' + JSON.stringify(b));
			console.log('c:' + JSON.stringify(c));
		});
	</script>
<body>
</body>
</html>

        运行结果:

a:{"name":"lisi","age":30,"company":{"name":"阿里巴巴","address":"北京"},"stature":"172cm"}
b:{"name":"test","age":30,"company":{"name":"阿里巴巴","address":"北京"},"stature":"172cm"}
c:{"name":"lisi","age":30,"company":{"name":"阿里巴巴","address":"北京"},"stature":"172cm"}

         $.extend浅拷贝实例三,$.extend({},a,b)用法

<html>
<head>
</head>
	<meta charset="GBK">
	<title>StudyDemo03</title>
	<script type="text/javascript" src="jquery-1.8.3.js"></script>
	<script type="text/javascript">
		$(document).ready(function() {
			var a = {
				name : 'zhangshan',
				age : 28,
				company : {
					name : '腾讯',
					address : '深圳',
					size : 10000
				}
			};
			var b = {
				name : 'lisi',
				age : 30,
				company : {
					name : '阿里巴巴',
					address : '杭州'
				},
				stature : '172cm'
			};
			var c = $.extend({},a,b);
			console.log('a:' + JSON.stringify(a));
			console.log('b:' + JSON.stringify(b));
			console.log('c:' + JSON.stringify(c));
		});
	</script>
<body>
</body>
</html>

        运行结果:

a:{"name":"zhangshan","age":28,"company":{"name":"腾讯","address":"深圳","size":10000}}
b:{"name":"lisi","age":30,"company":{"name":"阿里巴巴","address":"杭州"},"stature":"172cm"}
c:{"name":"lisi","age":30,"company":{"name":"阿里巴巴","address":"杭州"},"stature":"172cm"}

        $.extend浅拷贝实例四,$.extend({},a,b)用法

<html>
<head>
</head>
	<meta charset="GBK">
	<title>StudyDemo04</title>
	<script type="text/javascript" src="jquery-1.8.3.js"></script>
	<script type="text/javascript">
		$(document).ready(function() {
			var a = {
				name : 'zhangshan',
				age : 28,
				company : {
					name : '腾讯',
					address : '深圳',
					size : 10000
				}
			};
			var b = {
				name : 'lisi',
				age : 30,
				company : {
					name : '阿里巴巴',
					address : '杭州'
				},
				stature : '172cm'
			};
			var c = $.extend({},a,b);
			a.name = 'zhangshan01';
			b.name = 'lisi01';
			b.company.address = 'shengzhen';
			console.log('a:' + JSON.stringify(a));
			console.log('b:' + JSON.stringify(b));
			console.log('c:' + JSON.stringify(c));
		});
	</script>
<body>
</body>
</html>

        运行结果:

a:{"name":"zhangshan01","age":28,"company":{"name":"腾讯","address":"深圳","size":10000}}
b:{"name":"lisi01","age":30,"company":{"name":"阿里巴巴","address":"shengzhen"},"stature":"172cm"}
c:{"name":"lisi","age":30,"company":{"name":"阿里巴巴","address":"shengzhen"},"stature":"172cm"}

        由$.extend浅拷贝实例三、实例四不难发现,$.extend({},a,b)方法会依次拷贝a、b对象,且b里面的对象是内存地址的拷贝(加上b.company.address = 'shengzhen';语句后执行结果可以看出)。

 

二.$.extend深拷贝

       $.extend深拷贝实例一,$.extend(true,a,b)用法

<html>
<head>
</head>
	<meta charset="GBK">
	<title>StudyDemo05</title>
	<script type="text/javascript" src="jquery-1.8.3.js"></script>
	<script type="text/javascript">
		$(document).ready(function() {
			var a = {
				name : 'zhangshan',
				age : 28,
				company : {
					name : '腾讯',
					address : '深圳',
					size : 10000
				}
			};
			var b = {
				name : 'lisi',
				age : 30,
				company : {
					name : '阿里巴巴',
					address : '杭州'
				},
				stature : '172cm'
			};
			var c = $.extend(true,a,b);
			console.log('a:' + JSON.stringify(a));
			console.log('b:' + JSON.stringify(b));
			console.log('c:' + JSON.stringify(c));
		});
	</script>
<body>
</body>
</html>

        运行结果:

a:{"name":"lisi","age":30,"company":{"name":"阿里巴巴","address":"杭州","size":10000},"stature":"172cm"}
b:{"name":"lisi","age":30,"company":{"name":"阿里巴巴","address":"杭州"},"stature":"172cm"}
c:{"name":"lisi","age":30,"company":{"name":"阿里巴巴","address":"杭州","size":10000},"stature":"172cm"}

        $.extend深拷贝实例二,$.extend(true,a,b)之后,修改b对象

<html>
<head>
</head>
	<meta charset="GBK">
	<title>StudyDemo06</title>
	<script type="text/javascript" src="jquery-1.8.3.js"></script>
	<script type="text/javascript">
		$(document).ready(function() {
			var a = {
				name : 'zhangshan',
				age : 28,
				company : {
					name : '腾讯',
					address : '深圳',
					size : 10000
				}
			};
			var b = {
				name : 'lisi',
				age : 30,
				company : {
					name : '阿里巴巴',
					address : '杭州'
				},
				stature : '172cm'
			};
			var c = $.extend(true,a,b);
			b.name = 'test';
			b.company.address = '北京';
			console.log('a:' + JSON.stringify(a));
			console.log('b:' + JSON.stringify(b));
			console.log('c:' + JSON.stringify(c));
		});
	</script>
<body>
</body>
</html>

        运行结果:

a:{"name":"lisi","age":30,"company":{"name":"阿里巴巴","address":"杭州","size":10000},"stature":"172cm"}
b:{"name":"test","age":30,"company":{"name":"阿里巴巴","address":"北京"},"stature":"172cm"}
c:{"name":"lisi","age":30,"company":{"name":"阿里巴巴","address":"杭州","size":10000},"stature":"172cm"}

        $.extend深拷贝实例三

<html>
<head>
</head>
	<meta charset="GBK">
	<title>StudyDemo07</title>
	<script type="text/javascript" src="jquery-1.8.3.js"></script>
	<script type="text/javascript">
		$(document).ready(function() {
			var a = {
				name : 'zhangshan',
				age : 28,
				company : {
					name : '腾讯',
					address : '深圳',
					size : 10000
				}
			};
			var b = {
				name : 'lisi',
				age : 30,
				company : {
					name : '阿里巴巴',
					address : '杭州'
				},
				stature : '172cm'
			};
			var c = $.extend(true,{},a,b);
			console.log('a:' + JSON.stringify(a));
			console.log('b:' + JSON.stringify(b));
			console.log('c:' + JSON.stringify(c));
		});
	</script>
<body>
</body>
</html>

        运行结果:

a:{"name":"zhangshan","age":28,"company":{"name":"腾讯","address":"深圳","size":10000}}
b:{"name":"lisi","age":30,"company":{"name":"阿里巴巴","address":"杭州"},"stature":"172cm"}
c:{"name":"lisi","age":30,"company":{"name":"阿里巴巴","address":"杭州","size":10000},"stature":"172cm"}

        $.extend深拷贝实例四,修改b对象

<html>
<head>
</head>
	<meta charset="GBK">
	<title>StudyDemo08</title>
	<script type="text/javascript" src="jquery-1.8.3.js"></script>
	<script type="text/javascript">
		$(document).ready(function() {
			var a = {
				name : 'zhangshan',
				age : 28,
				company : {
					name : '腾讯',
					address : '深圳',
					size : 10000
				}
			};
			var b = {
				name : 'lisi',
				age : 30,
				company : {
					name : '阿里巴巴',
					address : '杭州'
				},
				stature : '172cm'
			};
			var c = $.extend(true,{},a,b);
			a.name = 'zhangshan01';
			b.name = 'lisi01';
			b.company.address = 'shengzhen';
			console.log('a:' + JSON.stringify(a));
			console.log('b:' + JSON.stringify(b));
			console.log('c:' + JSON.stringify(c));
		});
	</script>
<body>
</body>
</html>

        运行结果:

a:{"name":"zhangshan01","age":28,"company":{"name":"腾讯","address":"深圳","size":10000}}
b:{"name":"lisi01","age":30,"company":{"name":"阿里巴巴","address":"shengzhen"},"stature":"172cm"}
c:{"name":"lisi","age":30,"company":{"name":"阿里巴巴","address":"杭州","size":10000},"stature":"172cm"}

 

三.$.extend源代码

        查看分析$.extend源代码,我们就不难理解上面实例的运行结果了

jQuery.extend = jQuery.fn.extend = function() {
	var options, name, src, copy, copyIsArray, clone,
		target = arguments[0] || {},
		i = 1,
		length = arguments.length,
		deep = false;

	// Handle a deep copy situation
	if ( typeof target === "boolean" ) {
		deep = target;
		target = arguments[1] || {};
		// skip the boolean and the target
		i = 2;
	}

	// 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
	if ( length === i ) {
		target = this;
		--i;
	}

	for ( ; i < length; i++ ) {
		// Only deal with non-null/undefined values
		if ( (options = arguments[ i ]) != null ) {
			// Extend the base object
			for ( name in options ) {
				src = target[ name ];
				copy = options[ name ];

				// Prevent never-ending loop
				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;
						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;
};

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值