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; };