深拷贝和浅拷贝区别
浅拷贝:将原数组或者原对象的引用值直接赋给新对象或者新数组只是原对象的有一个引用
改变新数组或者新对象,原数组或者原对象也会发生改变
深拷贝:创建一个新的对象和数组,将对象的各项属性的值拷贝过来,是一个值不是一个引用
改变新数组或者新对象不会,原数组或者原对象不会发生改变
深拷贝和浅拷贝的使用场景
深拷贝和浅拷贝一般都用于操作object和array
深拷贝:比如想对某个数组 或 对象的值进行修改,但是又要保留原来数组 或 对象的值不被修改,此时就可以用深拷贝来创建一个新的数组 或 对象,从而达到操作(修改)新的数组 或 对象时,保留原来数组 或 对象。
浅拷贝:比如想对某个数组 或 对象的值进行修改,但是又要想新数组和原数组中的数据同步,此时可以用浅拷贝,创建一个新的数组或者对象,对原数组的数据引用,从而达到操作新的数组或者新的对象,数据同步
深拷贝和浅拷贝的堆中的区别
const a =[1,2,3,4,5,{x:1}]
//a是基本数据类型
//[1,2,3,4,5]是引用数据类型
//数组中数据是基本数据类型
//数组中对象和数组是引用数据类型
浅拷贝:重新在堆中创建内存,拷贝前后对象的基本数据相互不影响,但是拷贝前后对象的引用类型是共享同一块内存,会相互影响
深拷贝:从堆内存中开辟一个新的区域存放新的数组或者新的对象,是对象的子怼进行递归拷贝,前后对象相互不影响
浅拷贝
Array.prototype.sliice()属于浅拷贝
原型浅拷贝
arr.slice([begin[, end]])
begin,end都是可选的
begin:是从下标为几开始
如果是负数则数组中的倒数几个元素开始提取
end:是从下标为几终止
如果是负数则数组中的倒数几个元素开始终止
var arr = [2, 3, 4,{x:10},[1,2]]
var newArr = arr.slice()
newArr[4][1] = 20
newArr[3].x = 30
newArr[0]=1
console.log(arr) //0: 2,1: 3,2: 4,3: {x: 30},4:[1, 20]
console.log(newArr)0: 1,1: 3,2: 4,3: {x: 30},4:[1, 20]
深拷贝
递归深拷贝
var obj = {
// 原数据,包含字符串,对象,函数,数组等不同类型
name: "test",
main: {
a: 1,
b: 2
},
fn: function () { },
freinds: [1, 2, 3]
}
function deepClone(obj) {
// 创建一个变量来存储拷贝后的对象或数组
var copy
// 判断拷贝的数据类型
if (obj instanceof Array) {
copy = [] // 初始化一个数组
for (var i = 0; i < obj.length; i++) {
// 递归调用
copy[i] = deepClone(obj[i])
}
return copy
} else if (obj instanceof Object) {
copy = {} // 初始化一个对象
for (var key in obj) {
// 递归调用
copy[key] = deepClone(obj[key])
}
return copy
} else {
// 如果是其他数据类型,则直接赋值给新的变量
return obj
}
}
var newObj = deepClone(obj)
console.log(newObj) // 输出拷贝后的对象或数组,与原数据完全相同,但内存地址不同。