`

浅拷贝深拷贝之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;
};

 

分享到:
评论

相关推荐

    underscore.extend与$.extend实例比较分析

    在JavaScript开发中,`underscore` 和 `jQuery` 都提供了扩展对象的功能,即 `_.extend()` 和 `$.extend()` 方法。这两个方法允许开发者合并一个或多个对象的属性到目标对象中,实现对象间的属性拷贝。本文将深入...

    jQuery的$.extend 浅拷贝与深拷贝

    主要介绍了jQuery的$.extend 浅拷贝与深拷贝的相关资料,需要的朋友可以参考下

    jQuery中$.extend()用法实例

    在jQuery库中,`$.extend()`是一个非常实用的方法,它用于合并两个或更多对象的属性到一个目标对象中。这个方法允许我们创建复杂的对象结构,同时也方便了代码的复用和扩展。下面是关于`$.extend()`方法的详细解析:...

    Js-$.extend扩展方法使方法参数更灵活.docx

    `$.extend()`还有其他一些高级用法,例如深拷贝和浅拷贝。当`deep`参数设置为`true`时,`$.extend(true, target, object1, [objectN])`会执行深拷贝,不仅复制对象的属性,还会递归地复制嵌套的对象和数组。这对于...

    jQuery.extend和jQuery.fn.extend的区别

    1. `jQuery.extend`用于合并和扩展对象,可以进行浅拷贝或深拷贝,通常用于配置选项的合并。 2. `jQuery.fn.extend`用于向jQuery对象添加新的方法,增强了jQuery的功能性,使我们可以自定义jQuery插件。 理解这两个...

    jQuery.extend

    jQuery.extend还提供了深拷贝和浅拷贝的功能。当你传递`true`作为第一个参数时,它会执行深拷贝,这意味着如果对象的属性包含其他对象,那么这些对象也会被递归复制。 ```javascript var obj1 = {a: {b: 1}}; var ...

    jQuery使用$.extend(true,object1, object2);实现深拷贝对象的方法分析

    本文实例讲述了jQuery使用$.extend(true,object1, object2);实现深拷贝对象的方法。分享给大家供大家参考,具体如下: 语法:jQuery.extend( [deep ], target, object1 [, objectN ] ) 深浅拷贝对应的参数就是[deep]...

    Web前端开发技术-Jquery其他方法.pptx

    $.extend()方法:基本语法$.extend([deep], target, object1, [objectN])。 target是要拷贝的目标对象,后面可以跟多个对象(object1~objectN) 当不同对象中存在相同的成员名时,后面对象成员会覆盖前面的对象成员 ...

    $.extend 的一个小问题

    $.extend方法主要有两个版本:浅拷贝和深拷贝。当`deep`参数为`true`时,$.extend执行深拷贝,递归地复制源对象中的所有属性到目标对象,包括嵌套的对象和数组。如果`deep`为`false`或未提供,则执行浅拷贝,只复制...

    jQuery中extends详解[借鉴].pdf

    总结来说,`jQuery.extend`是jQuery中用于对象合并和扩展的重要工具,它支持浅拷贝、深拷贝以及向jQuery全局对象和实例对象扩展方法。理解并熟练掌握`jQuery.extend`的用法,将极大地提高JavaScript编程的效率和灵活...

    分析了一下JQuery中的extend方法实现原理

    总的来说,`jQuery.extend`通过递归的方式实现了深拷贝或浅拷贝,允许开发者灵活地合并和扩展JavaScript对象。这个方法在实际开发中非常实用,能够帮助我们构建更加复杂的数据结构,同时保持代码的清晰和简洁。理解`...

    jQuery Utilities 分类下的函数(或属性)的实现方式分析

    这个函数的实现基于JavaScript的原型链和对象属性复制特性,可以处理浅拷贝和深拷贝的情况。 在事件处理方面,`$.on()`和`$.off()`分别用于绑定和解绑事件。`$.on()`不仅可以绑定单个事件,还可以绑定多个事件,...

    Jquery 源代码分析

    $.fn.extend()主要用于扩展jQuery对象的方法,而$.extend()则用于合并对象属性,实现对象的深拷贝或浅拷贝。 三、事件处理 1. **事件绑定与触发**:jQuery提供了一系列的事件处理函数,如bind(), unbind(), ...

    jQueryExtendDemo

    `jQuery.extend()`主要有两种用法:浅拷贝和深拷贝。基本语法如下: ```javascript $.extend(target, object1, [objectN]); ``` - `target`:目标对象,它的属性将被其他对象的属性覆盖或添加。 - `object1`、`...

    JQuery中extend的用法实例分析

    总结来说,`jQuery.extend` 是一个强大的工具,允许开发者合并和扩展 JavaScript 对象,无论是浅拷贝还是深拷贝,都能灵活处理,极大地提高了代码的可维护性和可扩展性。在开发 jQuery 插件或处理复杂数据结构时,它...

    第十二课 工具函数1

    `deep` 决定是否进行深拷贝(默认为浅拷贝),`target` 是目标对象,`objN` 是要合并的对象。深拷贝会递归复制对象的所有属性,而浅拷贝只复制顶层属性。例如: ```javascript var obj1 = {num: 100, data: {aaa: ...

    jQuery帮助文档

    - `$.extend()`方法用于合并对象,是实现深拷贝和浅拷贝的关键。 - `$.getScript()`和`$.getJSON()`简化了动态加载脚本和JSON数据的过程。 这些帮助文档提供了关于jQuery 1.4至1.8版本的核心功能和API的详细指南...

    2014-10-13-深入理解jQuery(3)——extend1

    总的来说,`jQuery.extend`方法是jQuery中处理对象和数组合并的核心,它可以灵活地进行浅拷贝或深拷贝,以及扩展jQuery类和实例的方法。通过对源码的解析,我们可以看到它如何巧妙地处理各种情况,确保数据的正确...

Global site tag (gtag.js) - Google Analytics