js实现(一层 / 多层)对象/数组的深拷贝

如何区分深拷贝与浅拷贝,简单点来说,就是假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝;如果B没变,那就是深拷贝。
(上面的复制在程序中可以看做是赋值关系)

一、多层嵌套的深拷贝

1、封装函数——遍历的方式实现对象/数组深拷贝
// 深拷贝函数
    const deepCopy = (obj) => {
      const cloneTarget = Array.isArray(obj) ? [] : {};
      if (obj === null) return obj;
      if (obj instanceof Date) return new Date(obj);
      if (obj instanceof RegExp) return new RegExp(obj);
      if (typeof obj !== 'object') return obj;
      for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
          cloneTarget[key] = deepCopy(obj[key]);
        }
      }
      return cloneTarget;
    }

    const objTest = {
      date: new Date(),
      reg: new RegExp(/[a-z]/g),
      fn: () => { console.log(1) },
      a: 1,
      arr: [1, [2, 3]],
      obj: {
        name: 'winne',
        like: ['a', 'b']
      },
      b: null,
    }
    console.log(deepCopy(objTest))
	 // ------------分割线---------------------
    var obj = {
      a:1,
      b:{bb:2},
      c:[1,2,3]
    }
    var arr = [1,2,3,4,5,[22,33,[44,88]]]

    var copyObj = deepCopy(obj);
    // var copyObj = obj; // 如果不进行深拷贝,那么修改copyObj的时候原先对象也会受到影响
    copyObj.b.bb = 111;
    console.log(obj)
    console.log(copyObj)

    var copyArr = deepCopy(arr);
    // var copyArr = arr;  // 如果不进行深拷贝,那么修改copyArr的时候原先数组也受到影响
    copyArr[5].push(999)
    console.log(arr)
    console.log(copyArr)

2、JSON.parse/JSON.stringify方式——实现对象/数组的深拷贝

使用这个方法来进行深拷贝,如果对象中存在undefined、任意的函数以及 symbol 作为对象属性值时 JSON.stringify() 对跳过(忽略)它们进行序列化的隐患。
详细阅读:JSON.stringify() 九大特性

// 对象
var obj = {
      a:1,
      b:{bb:2},
      c:[1,2,3]
    }
var copyObj = JSON.parse( JSON.stringify(obj) ) // 这里实现了对obj的深拷贝
copyObj.b.bb = 666
console.log(obj) // {a:1,b:{bb:2},c:[1,2,3]}
console.log(copyObj) // {a:1,b:{bb:666},c:[1,2,3]}

// 数组
var arr = [1, 2, [6], 7, [8, [9]]]
var copyArr = JSON.parse(JSON.stringify(arr)) // 这里实现了对arr的深拷贝
copyArr[2].push(0)
console.log(arr) // [1, 2, [6], 7, [8, [9]]]
console.log(copyArr) // [1, 2, [6, 0], 7, [8, [9]]]

二、一层数组或对象的深拷贝

1、slice()—— 一层数组的深拷贝
var arr = [1, 2, 3]
var newArr = arr.slice()
arr.push(4)
console.log(arr) // [1, 2, 3, 4]
console.log(newArr) // [1, 2, 3]
2、concat()—— 一层数组的深拷贝
var arr = [1, 2, 3]
var newArr = arr.concat()
arr.push(4)
console.log(arr) // [1, 2, 3, 4]
console.log(newArr) // [1, 2, 3]
3、解构赋值—— 一层数组 / 对象的深拷贝
// 数组
var arr = [1, 2, 3]
var newArr = [...arr]
arr.push(4)
console.log(arr) // [1, 2, 3, 4]
console.log(newArr) // [1, 2, 3]
// 对象
var obj = { name: 'winne' }
var newObj = { ...obj }
obj.name = 'xf'
console.log(obj) // {name: "xf"}
console.log(newObj) // {name: "winne"}
4、Object.assign()—— 一层对象的深拷贝
var obj = { name: 'winne' }
var newObj = Object.assign({}, obj)
obj.age = 20
console.log(obj) // {name: "winne", age: 20}
console.log(newObj) // {name: "winne"}
5、filter()—— 一层数组的深拷贝
var arr = [1, 2]
var newArr = arr.filter((item) => {
  return true
})
arr.push(88)
console.log(arr) // [1, 2, 88]
console.log(newArr) // [1, 2]
6、map()—— 一层数组的深拷贝
var arr = [1, 2]
var newArr = arr.map((item) => {
  return item
})
arr.push(88)
console.log(arr) // [1, 2, 88]
console.log(newArr) // [1, 2]

参考原文:
https://www.cnblogs.com/renbo/p/9563050.html

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值