数组是引用类型,至于引用数据类型和基础数据类型,可以看下js相关文档。
有些时候我们需要复制一个数组,用来进行某些操作
数组复制分为浅拷贝和深拷贝
浅拷贝:
当修改复制之后的数组,原数组的值也会发生改变
浅拷贝的几种方法
1. 直接赋值
let arr = [1, 2, 3]
let arr2 = arr
arr2[0] = 0
console.log(`arr: ${arr}`)
console.log(`arr2: ${arr2}`)
2. ES6展开操作符, 这种你会发现第一层修改了没受影响,但是第二层的一旦改变,两者都会发生改变, 这也是浅拷贝
const arr1 = [1, 2, 3, {c: 1}]
const arr2 = [...arr1]
arr1[3].c = 2
console.log(arr1) // [ 1, 2, 3, { c: 2 } ]
console.log(arr2) // [ 1, 2, 3, { c: 2 } ]
3. concat, slice, 跟上面的运算符一样
const arr1 = [1, 2, 3, {a: 1}]
const arr2 = arr1.concat()
const arr3 = arr1.slice(0)
arr2[3].a = 3
console.log(arr1) // [ 1, 2, 3, { a: 3 } ]
console.log(arr2) // [ 1, 2, 3, { a: 3 } ]
console.log(arr3) // [ 1, 2, 3, { a: 3 } ]
4. for循环, 同上
const arr1 = [1, 2, 3, {a: 1}]
let arr2 = []
for(let i = 0; i < arr1.length; i++) {
arr2.push(arr1[i])
}
arr2[3].a = 2
console.log(arr1) // [ 1, 2, 3, { a: 2 } ]
console.log(arr2) // [ 1, 2, 3, { a: 2 } ]
此外Object.assign也是浅拷贝
下面来看下深拷贝,在此介绍两种方法
1.JSON.parse(JSON.stringify(arr))
const arr1 = [1, 2, 3, {a: 1}]
const arr2 = JSON.parse(JSON.stringify(arr1))
arr2[3].a = 2
console.log(arr1) // [ 1, 2, 3, { a: 1 } ]
console.log(arr2) // [ 1, 2, 3, { a: 2 } ]
2. 自己使用递归的方式写,下面是实现的代码,只是数组层面,对象也可以实现,应该是newArr判断下类型,之所以非数组和非对象设置为空,是为了三重运算成功,只考虑这两种类型
const newArr = Object.prototype.toString.call(arr).slice(8, -1) === 'Array' ? [] : Object.prototype.toString.call(arr).slice(8, -1) === 'Object' ? {} : ''
const arr1 = [1, 2, 3, {a: 1}, {a: 2, b: {a: 1, d: [{a: 1, b: 2}]}}]
function deepCopy(arr) {
const newArr = []
for(let i in arr) {
console.log(arr[i])
if (typeof arr[i] === 'object') {
newArr[i] = deepCopy(arr[i])
} else {
newArr[i] = arr[i]
}
}
console.log(newArr)
return newArr
}
const arr2 = deepCopy(arr1)
arr2[4].b.d[0].a = 2
console.log('arr1')
console.log(arr1) // [1,2,3,{"a":1},{"a":2,"b":{"a":1,"d":[{"a":1,"b":2}]}}]
console.log('arr2')
console.log(arr2) // [1,2,3,{"a":1},{"a":2,"b":{"a":1,"d":[{"a":2,"b":2}]}}]
差不多就这些,借鉴了网上的一些方法