谈谈JS中的深度拷贝

谈谈JS中的浅拷贝这篇文章中,我们提到了JS中的浅拷贝,也知道浅拷贝产生的原因,以及浅拷贝只在引用型数据类型中出现,那么今天我们就来谈谈如何进行深度拷贝!
方法一:数组的concat与slice方法

var a = [1, 2, 3, 4, 5];
var b = a.slice();
// var b = a.concat();
b[0] = 12;
console.log(a);   //输出 [1, 2, 3, 4, 5]
console.log(b);   // 输出[12, 2, 3, 4, 5]

我们发现JS数组的这两个方法都能对数组进行深度复制。
缺点:
1、slice和concat方法只能用于数组
2、即使是像下面这种格式的也不能进行深度拷贝,因为第二层是对内存的引用

var a = [{
	x: 1,
	z: {
		b: 3
	}
}]
var c = a.slice();
// var c = a.concat();
c[0].x = 11;
c[0].z.b = 13;
console.log(a);  // a[0].x=11,  a[0].z.b=13
console.log(c);  // c[0].x=11,  c[0].z.b=13

方法二:ES6的解构方法

var a = [1, 2, 3, 4];
var b = [...a];
b[0] = 11;
console.log(a);  // 输出[1, 2, 3, 4]
console.log(b);  // 输出[11, 2, 3, 4]

缺点:只能解构数组,同样不能解构复杂的json,因为第二层同样是对内存的引用。

方法三:递归遍历复制

// 递归拷贝函数
function deepClone(obj){
    let objClone = Array.isArray(obj) ? [] : {};
    if(obj && typeof obj === "object"){
        for(key in obj){
            if(obj.hasOwnProperty(key)) {
                //判断ojb子元素是否为对象,如果是,递归复制
                if(obj[key]&&typeof obj[key] === "object"){
                    objClone[key] = deepClone(obj[key]);
                }else{
                    //如果不是,简单复制
                    objClone[key] = obj[key];
                }
            }
        }
    }
    return objClone;
} 

var a = [{
	x: 1,
	z: {
		b: 3
	}
}]
var c = deepClone(a);
c[0].x = 11;
c[0].z.b = 13;
console.log(a);  // 输出a[0].x=1,  a[0].z.b=3
console.log(c);  // 输出c[0].x=11,  c[0].z.b=13

方法四:parse和stringify方法

// stringify和parse的拷贝函数
function deepClone(val) {
	var obj = Array.isArray(val) ? [] : {};
	// 转化为字符串
	obj = JSON.stringify(val);
	// 返回对象
	return JSON.parse(obj);
}

var a = [{
	x: 1,
	z: {
		b: 3
	}
}]
var c = deepClone(a);
c[0].x = 11;
c[0].z.b = 13;
console.log(a);  // a[0].x=1,  a[0].z.b=3
console.log(c);  // c[0].x=11,  c[0].z.b=13

方法五:jq的$.extend方法

/**

    $.extend([deep], target, object1[,objectN])
    deep: 拷贝类型,true为深度拷贝,false为浅拷贝
    target:目标对象,其他对象将被附加到该对象上
    object1[,objectN]:需要拷贝的对象,可以是多个对象

*/
var a = [{
	x: 1,
	z: {
		b: 3
	}
}]
var c = $.extend(true, [], a);
c[0].x = 11;
c[0].z.b = 13;
console.log(a);  // a[0].x=1,  a[0].z.b=3
console.log(c);  // c[0].x=11,  c[0].z.b=13

以上为常用的五种深度拷贝方法,希望对大家有所帮助,个人技术有限,如果大家还有其他更好的方法,欢迎留言,我会及时更新的,祝大家新年快乐!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值