深、浅拷贝

浅拷贝:创建一个新对象,如果拷贝对象式基础数据类型,复制值给新对象。如果式引用数据类型,复制内存中的地址给新对象。
深拷贝:对于引用数据类型,在堆内存中完全开辟一块地址,并将对象复制过来存放。
浅拷贝的方法:
1.es6中的object.assign()

let target = {};
let source = { a: { b: 2 } };
Object.assign(target, source);
console.log(target); // { a: { b: 10 } }; 
source.a.b = 10; 
console.log(source); // { a: { b: 10 } }; 
console.log(target); // { a: { b: 10 } };

2.数组的slice()方法

let arr = [1, 2, {val: 4}];
let newArr = arr.slice();
newArr[2].val = 1000;
console.log(arr);  //[ 1, 2, { val: 1000 } ]

3.数组的contact()方法

let arr = [1, 2, 3];
let newArr = arr.concat();
newArr[1] = 100;
console.log(arr);  // [ 1, 2, 3 ]
console.log(newArr); // [ 1, 100, 3 ]

4.扩展运算符…

let obj = {a:1,b:{c:1}}
let obj2 = {...obj}
obj.a = 2
console.log(obj)  //{a:2,b:{c:1}} console.log(obj2); //{a:1,b:{c:1}}
obj.b.c = 2
console.log(obj)  //{a:2,b:{c:2}} console.log(obj2); //{a:1,b:{c:2}}
/* 数组的拷贝 */
let arr = [1, 2, 3];
let newArr = [...arr]; //跟arr.slice()是一样的效果

5.手工实现
1.区分基础数据类型和引用数据类型
2.对应用数据类性开辟一个新的存储,并且拷贝一层对象属性。

function shallowClone(target) => {
//判断数据类型
	if (typeof target === 'object' && target !== null) {
	//开辟存储空间,判断是数组还是对象
		const cloneTarget = Array.isArray(target) ? []:{};
		//循环遍历原对象,取出对象属性赋给新对象,在进行值的拷贝
		for (let prop in target) {
			if (target.hasOwnProperty[prop]);
			cloneTarget[prop] = target[prop];
		}
		return cloneTarget;
	} else {
	return target
	}
}

深拷贝:
1.JSON.stringify()

let obj1 = {a:1, b:[1,2,3]}
let str = JSON.stringify(obj1);
let obj2 = JSON.parse(str);
console.log(obj2);

注意!
拷贝的对象的值中如果有函数、undefined、symbol 这几种类型,经过 JSON.stringify 序列化之后的字符串中这个键值对会消失;
拷贝 Date 引用类型会变成字符串;
无法拷贝不可枚举的属性;
无法拷贝对象的原型链;
拷贝 RegExp 引用类型会变成空对象;
对象中含有 NaN、Infinity 以及 -Infinity,JSON 序列化的结果会变成 null;
无法拷贝对象的循环应用,即对象成环 (obj[key] = obj)。
手写递归实现:
通过for- in遍历传入参数的属性值,如果只是引用类型则再次递归调用该函数,如果是基础数据类型就直接复制。

let obj = {
	a: {
		b:1
	}
}
function deepClone(obj) {
	let cloneObj = {}
	for (let key in obj) {
		if (typeof key === 'onject') {
			cloneObj[key] = deepClone(obj[key])
		}else {
			cloneObj[key] = obj[key]
		}
	}
	return cloneObj
}

这个深拷贝函数并不能复制不可枚举的属性以及 Symbol 类型;
这种方法只是针对普通的引用类型的值做递归复制,而对于 Array、Date、RegExp、Error、Function 这样的引用类型并不能正确地拷贝;
对象的属性里面成环,即循环引用没有解决。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值