本帖最后由 JoyZhang 于 2020-12-7 09:34 编辑
slice拷贝的缺点刚开始对数组的深拷贝的理解是这样的
[JavaScript] 纯文本查看 复制代码 let arr = [1,2,3,4,5,6]
let a1 = arr.slice()
a1[0] = 2
console.log(arr, a1) // [1, 2, 3, 4, 5, 6] [2, 2, 3, 4, 5, 6]
后来听说别人这样不是“深拷贝”,自己不知道什么原因,思考后想到如果数组里面存在对象的话应该就不行了,所以
[JavaScript] 纯文本查看 复制代码 let arr = [1,2,3,{name: 'ww'},{name: 'ls'}]
let a1 = arr.slice()
a1[4].name = 'ww'
console.log(arr, a1)
// [1,2,3,{name: 'ww'},{name: 'ww'}]
// [1,2,3,{name: 'ww'},{name: 'ww'}]
当数组中有复杂类型的时候,发现slice对数组拷贝后,改变新数组里面的复杂类型的值原数组也会改变,
然后我查了一些资料后得出结论: 当数组里全是简单类型的时候slice是深拷贝,当数组里有复杂类型的时候,slice是浅拷贝,综上可以说slice是浅拷贝
那咱们看看什么是深拷贝
[JavaScript] 纯文本查看 复制代码 JSON.parse(JSON.stringify())
// JSON.stringify(obj)将JSON转为字符串
// JSON.parse(string)将字符串转为JSON格式
同样它的缺陷也很明显,详情请看这篇文章:https://www.jianshu.com/p/b084dfaad501
思路:
- 如果是简单类型直接返回
- 如果是复杂类型
- 1、数组 cloneTarget = []
- 2、对象 cloneTarget = {}
- 如果嵌套有数组中嵌套对象或者对象中嵌套对象等
- clone函数就循环引用
[JavaScript] 纯文本查看 复制代码 function clone(target) {
if (typeof target !== 'object') return target // 考虑简单类型
let cloneTarget = Array.isArray(target) ? [] : {} // 考虑数组还是对象
for (const key in target) {
cloneTarget[key] = clone(target[key]) // 考虑嵌套
}
return cloneTarget
}
let str = '1'
let arr = [1, 2, 3, 4, { name: 'zs' }]
let obj = { name: 'zs', age: 19 }
let cloneStr = clone(str)
console.log(cloneStr)
let cloneArr = clone(arr)
console.log(arr)
cloneArr[4].name = 'ls'
console.log(cloneArr)
console.log(arr)
let cloneObj = clone(obj)
cloneObj.name = 'ww'
console.log(cloneObj)
console.log(obj)
这个已经基本可以满足我们最基本的要求了
|