浅复制是对对象地址的复制,并没 有开辟新的栈,也就是复制的结果是两个对象指向同一个地址,修改其中一个对象的属性,则另一个对象的属性也会改变
深复制则是开辟新的栈,两个对象对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性
简单来说,浅复制只复制一层对象的属性,而深复制则递归复制了所有层级。
一、对于第一级元素是基本类型变量(如number,String,boolean)的简单数组
1、直接遍历
var array = [1,2,3.4] function copyFn(arr){ let newArr = [] for(let i of arr){ newArr.push(i) } return newArr; } var copyArr = copyFn(array); copyArr[0] = 500; console.log(array); console.log(copyArr)
2、slice 从某个已有的数组返回选定的元素[复制](返回一个新的数组) slice(start,end)
var arr1= [1,2,3,4] var arr2 = arr1.slice(); arr2[0]=500; console.log(arr1); console.log(arr2); //[1, 2, 3, 4] // [500, 2, 3, 4]
3、数组拼接 concat
var arr1= [1,2,3,4] var arr2 = arr1.concat(); arr2[0]=500; console.log(arr1); console.log(arr2); //[1, 2, 3, 4] //[500, 2, 3, 4]
二、对于第一级数组元素是对象或者数组引用类型变量的数组【浅拷贝实现】
实现浅拷贝(解决改变以防其他也改变的情况):
1、Object.assign()
语法:Object.assign(target,...sources)【ES6】
如果目标对象中的属性具有相同的键,则属性将被源对象中的属性覆盖。后面的源对象的属性将类似地覆盖前面的源对象的属性。
Object.assign
方法只会拷贝源对象自身的并且可枚举的属性到目标对象。
var obj = { name:'小红', age:20 } var copyObj = Object.assign({},obj) copyObj.name='小明' "小明" copyObj.age = 24 24 console.log(obj) console.log(copyObj) //{name: "小红", age: 20} //{name: "小明", age: 24}
2、扩展运算符(...)
数组拷贝,实际上展开语法和Object.assign()行为一致,执行的都是浅拷贝(之遍历一次)
var obj = { name:'小红', age:20 } var copyObj = {...obj} copyObj.name='小明' "小明" copyObj.age = 24 24 console.log(obj) console.log(copyObj) // {name: "小红", age: 20} // {name: "小明", age: 24}
思考:但是如果代码(多层嵌套)如下:
var obj = { name : '小红', hobby:{ hobby1:'羽毛球', hobby2:'篮球' } } var copyObj = Object.assign({},obj) copyObj.hobby.hobby1 = '游泳' console.log(obj) console.log(copyObj) //{name: "小红", hobby: {…}} | hobby: {hobby1: "游泳", hobby2: "篮球"}name: "小红" //{name: "小红", hobby: {…}} | hobby: {hobby1: "游泳", hobby2: "篮球"}name: "小红"
不难发现,多曾嵌套的对象并没有成功,出现的现象时只要改其中一个另外一有个跟着改变,所以浅拷贝只能拷贝一层,要实现拷贝多层需要使用深拷贝
三、拷贝多层,每一级数据都会被拷贝【深拷贝】
1、JSON.parse(JSON.stringify(object))【常用】
var obj = {
name:'Jay',
song:{
first:'蜗牛',
second:'屋顶'
}
}
var copyObj = JSON.parse(JSON.stringify(obj));
obj.song.first = '不能说的秘密';
console.log(obj.song.first);
console.log(copyObj.song.first);
// 不能说的秘密
//蜗牛
总结一下
参考:
知乎 :https://www.zhihu.com/question/23031215
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Spread_syntax
CSDN博客:https://blog.csdn.net/qq_39207948/article/details/81067482