学习深浅拷贝

深浅拷贝

所谓深浅拷贝,其实都是进行复制,主要区别在于复制出来的新对象和原来的对象是否会相互影响

B复制A,修改A | B 互不影响,为深拷贝

B复制A,修改A | B 互相影响,为浅拷贝

浅拷贝

举个栗子:

let oldObj = [1,2,3,4,5,6]
let newObj = oldObj
newObj[2] = 9
 // newObj  [1, 2, 9, 4, 5, 6]
 // oldObj  [1, 2, 9, 4, 5, 6]

再举个栗子:

let oldObj = { a:1, b:'xyz', c:[ 1, 2, 3]}
let newObj = oldObj
oldObj.c[1] = 9
 // newObj { a:1, b:'xyz', c:[ 1, 9, 3]}
 // oldObj { a:1, b:'xyz', c:[ 1, 9, 3]}


let oldObj1 = { a:1, b:'xyz', c:[ 1, 2, 3]}
let newObj1 = Object.assign(oldObj1)
newObj1.c[2] = 111
 // newObj { a:1, b:'xyz', c:[ 1, 2, 111]}
 // oldObj { a:1, b:'xyz', c:[ 1, 2, 111]}

可以明显的看出,根据oldObj复制出的newObj变量,在更改时,会互相影响,这就是浅拷贝

深拷贝

举个栗子: 还是上述的栗子

let oldObj = [1,2,3,4,5,6]
let newObj = oldObj.slice()
newObj[3] = 111
// newObj  [1, 2, 3, 111, 5, 6]
// oldObj  [1, 2, 3, 4, 5, 6]



let oldObj = [1,2,3,4,5,6]
let newObj = oldObj.concat()
newObj[3] = 222
// newObj  [1, 2, 3, 222, 5, 6]
// oldObj  [1, 2, 3, 4, 5, 6]

上述两个栗子,貌似看似是进行了深拷贝,但这只是假象。当数据结构只有一层时,是进行了深拷贝;但是当数据结构为多层时,最外层是深拷贝,而内层只是拷贝了引用地址

举个栗子:

let oldObj = [1,2,3,4,[1,2,3,4,[1,2,3,4,5]]]
let newObj = oldObj.concat()
newObj[4][4][4] = 5555
oldObj[2] = 2222
// newObj  [1,2,3,4,[1,2,3,4,[1,2,3,4,5555]]]
// oldObj  [1,2222,3,4,[1,2,3,4,[1,2,3,4,5555]]]

再举个栗子:

let oldObj = { a:1, b:'xyz', c:[ 1, 2, 3]}
let newObj = JSON.parse(JSON.stringify(oldObj))
oldObj.c[2] = 333
// oldObj { a:1, b:'xyz', c:[ 1, 2, 333]}
// newObj { a:1, b:'xyz', c:[ 1, 2, 3]}

上述的栗子,并不是最好的深拷贝方法。如果能将多层数据一层一层的复制,那定是极好的!!!

简化版的递归拷贝 🌰:
1.

function deepClone(obj) {
  if (typeof obj !== "object") return;
  let newObj = Array.isArray(obj) ? [] : {};
  for (let i in obj) {
    if (obj.hasOwnProperty(i)) {
      newObj[i] = typeof obj[i] === "object" ? deepClone(obj[i]) : obj[i];
    }
  }
  return newObj;
}

let oldObj = [
  1,
  2,
  3,
  {
    a: "aa",
    b: "bb",
    func: function() {
      let x = 10,
        y = 25;
      return () => x + y;
    },
  },
];

let newObj = deepClone(oldObj);
console.log(newObj);
function deepClone(source) {
  //   精准判断是对象还是数组
  const targetObj = source.constructor === Array ? [] : {}; 
  // 遍历目标
  for (let keys in source) {
   	// 查看是否有指定的属性
    if (source.hasOwnProperty(keys)) {
      // 如果值是对象,就递归一下(此处并非精准判断类型)
      if (source[keys] && typeof source[keys] === "object") {
        targetObj[keys] = source[keys].constructor === Array ? [] : {};
        targetObj[keys] = deepClone(source[keys]);
      } else {
        // 如果不是,就直接赋值
        targetObj[keys] = source[keys];
      }
    }
  }
  return targetObj;
}

欢迎补充 以及 纠正

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值