目录
3.JSON.parse(JSON.stringify())(深拷贝)
一、浅拷贝(shallow copy)
浅拷贝是按位拷贝对象, 它会创建一个新对象 ,这个对象有着原始对象属性值的一份精确拷贝。 如果属性是基本类型,拷贝的就是基本类型的值;如果属性是内存地址(引用类型),拷贝的就是内存地址 ,因此如果其中一个对象改变了这个地址,就会影响到另一个对象。只复制指向某个对象的指针,而不复制对象本身,新旧对象共享一块内存。
浅拷贝是指对基本类型的值拷贝,以及对对象类型的地址拷贝。
//对基本类型(值拷贝)
var a = 1; //number 基本类型,string、Boolean
var b = a; //浅拷贝 - 值拷贝
b = 2; //改变b的值,并不会影响到a,因为浅拷贝对基本类型而言就是值拷贝
console.log(a); //a=1
//对对象类型(地址拷贝)
var p1 = { //对象类型
name:'jack'
age:12
}
var p2 = p1; //地址拷贝
p2.age = 20; //改变p2的值,会影响到p1,因为浅拷贝对对象类型会进行地址拷贝
console.log(p1.age) //p1.age = 20
实现:浅拷贝只是拷贝一层,更深层次对象级别的只拷贝引用(地址),所以改变新对象,旧对象也会改变,因为新旧对象共享一块内存。
二、深拷贝(deep copy)
深拷贝是指复制并创建一个一模一样的对象,不共享内存,修改新对象,旧对象保持不变。
浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。但深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。
三、拷贝方法
1.通过 Object.assign() 拷贝(一深二浅)
Object.assign(目标文件, 原文件) 是一种可以对非嵌套对象进行深拷贝的方法,如果对象中出现嵌套情况,那么其对被嵌套对象的行为就变成了普通的浅拷贝。
var p1 = { //对象类型
name:'jack'
age:12
toy:{ //嵌套对象类型
name: 'car'
}
}
var p2 = {}
object.assign(p2,p1)
p2.age = 20
console.log(p1.age) //p1.age = 12 //嵌套对象外的拷贝对象类型属于深拷贝
p2.toy.name = plane
console.log(p1.toy.name) //p1.toy.name = plane嵌套对象中的拷贝对象类型属于浅拷贝
注意:
- 当对象只有一级属性为深拷贝;
- 当对象中有多级属性时,二级属性后就是浅拷贝;
2.通过slice()和concat()拷贝(浅拷贝)
slice(begin,end):返回一个新的数组对象,这一对象是一个由 begin 和 end 决定的原数组的浅拷贝(包括 begin,不包括end).原数组元素不变
//Array.prototype.slice()
let arr = [1, 3, {
username: ' kobe'
}];
let arr2 = arr.slice();
arr3[2].username = 'wade'
console.log(arr); //arr[2] = 'wade'修改新对象会改到原对象
concat(array):合并两个新数组。原数组不变
//Array.prototype.concat()
let arr = [1, 3, {
username: 'kobe'
}];
let arr3=arr.concat();
arr2[2].username = 'wade';
console.log(arr); //arr[2] = 'wade'同样修改新对象会改到原对象
关于Array的slice和concat方法的补充说明:Array的slice和concat方法不修改原数组,只会返回一个浅复制了原数组中的元素的一个新数组。
3.JSON.parse(JSON.stringify())(深拷贝)
用JSON.stringify将对象转成JSON字符串,再用JSON.parse()把字符串解析成对象,一去一来,新的对象产生了,而且对象会开辟新的栈,实现深拷贝。
let arr = [1, 3, {
username: ' kobe'
}];
let arr4 = JSON.parse(JSON.stringify(arr));
arr4[2].username = 'wade';
console.log(arr, arr4)
//arr[2] = 'kobe' //原对象类型未修改
//arr4[2] = 'wade'
注意:这种方法可以实现数组或对象深拷贝,但不能处理函数
参考文章:
[1] 浪里行舟.《浅拷贝与深拷贝》,知乎,2018.12.23
[2]JavaScript百炼成仙.《聊聊JavaScript深拷贝和浅拷贝》.Bilibili.2022.3.9