javascript对浅拷贝和深拷贝的详解
前端之家收集整理的这篇文章主要介绍了
javascript对浅拷贝和深拷贝的详解,
前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
下面小编就为大家带来一篇浅谈JavaScript中面向对象的的深拷贝和浅拷贝。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。
1.浅拷贝:复制一份引用,所有引用对象都指向一份数据,并且都可以修改这份数据。
2.深拷贝(复杂):复制变量值,对于非基本类型的变量,则递归至基本类型变量后,再复制。
这里画一个简单的图来加深理解:
一、数组的深浅拷贝
在使用JavaScript对数组进行操作的时候,我们经常需要将数组进行备份,事实证明如果只是简单的将它赋予其他变量,那么我们只要更改其中的任何一个,然后其他的也会跟着改变,这就导致了问题的发生。
");//Export:数组的原始值:One,test,Three
document.writeln("数组的新值:" + arrto + "
");//Export:数组的新值:One,Three
像上面的这种直接赋值的方式就是浅拷贝,很多时候,这样并不是我们想要得到的结果,其实我们想要的是arr的值不变,不是吗?
方法一:js的slice函数
");//Export:数组的原始值:One,Two,Three
document.writeln("数组的新值:" + arrtoo + "
");//Export:数组的新值:One,set Map,Three
方法二:js的concat方法
");//Export:数组的原始值:One,Three
document.writeln("数组的新值:" + arrtooo + "
");//Export:数组的新值:One,set Map To,Three
方法扩展到JQ(
函数)下边:扩展静态
方法
//2. jQuery.fn.extend 把extend扩展到jq.fn下 且jQuery.fn = jQuery.prototype 扩展实例
方法
// 1.2.
功能相似
var options,name,src,copy,copyIsArray,clone,//定义一些变量
target = arguments[0] || {},//目标元素是【0】第一个元素$.extend( a,{ name : 'hello' },{ age : 30 } );
i = 1,//第一个元素的位置
length = arguments.length,//第一个个对象的元素
deep = false; //是否是深拷贝 默认 false不是
// Handle a deep copy situation 看是不是深拷贝情况
if ( typeof target === "boolean" ) { //是布尔值
deep = target;
target = arguments[1] || {}; //目标元素是第二个$.extend( true,a,b )
// 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 = {}; //变成一个空的jason
}
// extend jQuery itself if only one argument is passed看是不是插件情况
if ( length === i ) { //只写了一个对象 要把这个对象扩展到jq源码上 静态方法 或者是实例方法
target = this; //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;//跳出本次循环继续执行
// $.extend( a,{ name : a } ) );循环引用 a也是一个对象
}
// Recurse if we're merging plain objects or arrays深拷贝
if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
// 是深拷贝 且需有var b = { name : { age : 30 } }; 且b必须是对象自变量(jason) 或者是个数组
//递归
if ( copyIsArray ) { //数组
copyIsArray = false;
clone = src && jQuery.isArray(src) ? src : []; //定义一个空数组
} else {//jason
clone = src && jQuery.isPlainObject(src) ? src : {};//看原有的属性有没有且是不是jason定义一个空jason
}
// var a = { name : { job : 'it' } }; 看有没有原有的属性 有的话在原有的上边添加
// var b = { name : {age : 30} };
// $.extend( true,b );//a继承b
// console.log( a ); a{ name:{ job : 'it' ,age : 30}} 如果只有一个{} 则只有,age : 30
// Never move original objects,clone(a) them
target[ name ] = jQuery.extend( deep,copy );
//调用函数本身进行进一步的递归处理
// Don't bring in undefined values浅拷贝
} else if ( copy !== undefined ) {
target[ name ] = copy; //直接复制因为里边没有对象
}
}
}
}
// Return the modified object
return target;
};