A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© JoyZhang 中级黑马   /  2020-12-7 09:14  /  1664 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 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)

这个已经基本可以满足我们最基本的要求了










0 个回复

您需要登录后才可以回帖 登录 | 加入黑马