数组和对象的深浅克隆

数组克隆方法有哪些

  • ES6展开运算符

    let arr1 = [10,20,{name:'cmj'}];
    let arr2 = [...arr1];
    

    数组arr1中元素既有基本类型值,又有对象。把arr1中元素展开逐个赋值给arr2,最终arr2中元素与arr1全部相同,实现了数组的克隆。
    在这里插入图片描述
    由于数组和对象均为引用类型值,实际存储的是堆内存地址。arr2===arr1返回false说明arr1和arr2占用了不同的堆内存,可是数组中的对象元素在克隆后仍占用同一块堆内存。

    像这样,只把最外层克隆,而内层与原来的共用相同的堆地址,这种克隆称为浅克隆

    相对地,如果内层(无论多少层)的引用类型值与原来的占用不同的堆地址,这样的克隆即为深克隆

  • slice(0): 这种方式也是浅克隆

    let arr1 = [10,20,{name:'cmj'}];
    let arr2 = arr1.slice(0);
    

那深克隆如何实现呢?

  • 基于JSON把对象转换为字符串,再转换回对象。
    let arr2 = JSON.parse(JSON.stringify(arr1));
    
    在这里插入图片描述
    但这种方式有个小问题:正则对象会变为空对象{},而函数对象会变为null。
    在这里插入图片描述

自己实现数组/对象的深克隆

function _type(value){
	return Object.prototype.toString.call(value);
}

function _deepClone(obj){
	// 首先进行类型判断
	if(obj === null) return;
	if(typeof obj === 'function') return;     // 函数的深克隆没啥意义
	if(typeof obj !== 'object') return obj;    // 能进到这个判断里来的一定是基本类型值了
	if(_type(obj) === '[object RegExp]') return new RegExp(obj);    // 正则对象
	if(_type(obj) === '[object Date]') return new Date(obj);     // 日期对象
	
	
	// 下面的这些才是正经八百的对象和数组
	let newObj = new obj.constructor;   // 根据传进来的obj类型,创建一个新的该类型实例
	for(let key in obj){
		if(!obj.hasOwnProperty(key)) break;
		// newObj[key] = obj[key];      这样实现的只有一层,是浅克隆
		newObj[key] = _deepClone(obj[key]);    // 用递归实现多层深克隆 
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值