js 数组、对象的深拷贝

1.为什么有深拷贝
在js中数据被分为了基础类型和引用类型;
基础类型:String、Boolean、Number,Undefined、Null;
引用类型:对象、数组、函数;
基本类型和引用类型由于两者在内存中存储的方式不同,造成两者访问的方式也不同。其中,基本类型存储在内存的栈中,是按值访问;引用类型存储在内存的堆中,是按引用访问
例:
let num1 = 10;
let num2 = 20;
let arr1 = [1,2,3,4,5];
let arr2 = arr1;

由于arr1与arr2指向的是同一个内存,所以不管是修改了arr1还是arr2,内存里面的数据都会发生变化,导致所有指向该内存的变量均变化。
在内存中的存储如图:
在这里插入图片描述

实现深拷贝的方法:

1.使用递归的方式实现数组、对象的深拷贝
function deepClone(obj){
	// 判断要进行深拷贝的是数组还是对象
	var objClone = Array.isArray(obj)?[]:{};

	// 进行深拷贝的数值不能为空,并且是对象或者是数组
	if(obj && typeof obj === 'object'){
		for(let key in obj){
			// 判断自身是否有这个属性
			if(obj.hasOwnProperty(key)){
				// 判断属性是否为引用类型
				if(obj[key]&& typeof obj[key] === 'object'){
					objClone[key] = deepClone(obj[key]);
				}else{
					objClone[key] = obj[key];
				}
			}
		}
	}

	return objClone;
}
2.使用JSON.parse(JSON.stringify())

其过程利用JSON.stringify 将js对象序列化(JSON字符串),再使用JSON.parse来反序列化(还原)js对象;

注意事项:
  1. 如果obj里有函数,undefined,则序列化的结果会把函数或 undefined丢失;
  2. JSON.stringify()只能序列化对象的可枚举的自有属性,例如 如果obj中的对象是有构造函数生成的, 则使用JSON.parse(JSON.stringify(obj))深拷贝后,会丢弃对象的constructor;
  3. 如果obj里有RegExp、Error对象,则序列化的结果将只得到空对象;

代码示例

let oldArr = [1,2,3,4,5];

let oldObj = {
	name:"demo",
	age:'12',
	sex:'男',
	firend:{
		name:"test",
		age:'14'
	},
	hobby:function(){
		console.log("hobby")
	},
	data: new RegExp('\\w+'),
	isNaN:NaN
}

let newArr = deepClone(oldArr);
newArr[3] = 33;
console.log(newArr,'newArr',oldArr,'oldArr')

let newOjb = deepClone(oldObj);
newOjb.sex = '女';
console.log(newOjb,'newOjb',oldObj,'oldObj')


let jsonOjb = JSON.parse(JSON.stringify(oldObj));
jsonOjb.firend.age = '0';
console.log(jsonOjb,'jsonOjb',oldObj,'oldObj')
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值