浅拷贝和深拷贝

4 篇文章 0 订阅

现象:数组通过=赋值后,修改新数组会改变原数组。

解决方案:

1、用es6的扩展方法【...】,Object.assign() 仅限有一级数据的简单数据结构

2、先把数据JSON.stringify(),再JSON.parse()解析,此方法有局限,某些值拷贝后会发现变化

3、通用的复杂数据结构的深拷贝,参考:面试题之如何实现一个深拷贝 | 木易杨前端进阶

原理:

1、js中存储对象时的存储方式是用指针指向内存地址,用=赋值只是将指针赋给了新数据,实际指向的内存地址并没有变化。浅拷贝只是拷贝指针,深拷贝才是将指针连同内存一起拷贝。

2、(...)取出所有可遍历属性,拷贝到当前数组或对象中。

let bar = { a: 1, b: 2 };

let baz = { ...bar }; // { a: 1, b: 2 }

实际上等价于Object.assign

let bar = { a: 1, b: 2 };

let baz = Object.assign({}, bar); // { a: 1, b: 2 }

// 深拷贝方法1: 
const obj = { 
      a: {
        a1: 1,
        a2: { a22: 3 }
      },
      b: { b1: 4 },
      c: {
        c1: {
          c11: 12,
          c12: 13,
          c13: 14,
          c14: { c114: 9 }
        }
      }
 };
 this.clone(obj);

 clone(source: any): any {
    const target: any = {};
    for(var i in source) {
        if (source.hasOwnProperty(i)) {
            if (typeof source[i] === 'object') {
                target[i] = this.clone(source[i]); // 注意这里
            } else {
                target[i] = source[i];
            }
        }
    }
    return target;
  }
// 深拷贝方法2: 
let obj2 = {
      a: [1, 2, 3],
      b: {
        c: 2,
        d: 3
      }
  }

  this.deepClone(obj2);

  deepClone(obj) {
    function isObject(o) {
      return (typeof o === 'object' || typeof o === 'function') && o !== null
    }
    if (!isObject(obj)) {
      throw new Error('非对象')
    }
    let isArray = Array.isArray(obj)
    let newObj = isArray ? [...obj] : { ...obj }

    Reflect.ownKeys(newObj).forEach(key => {
      newObj[key] = isObject(obj[key]) ? this.deepClone(obj[key]) : obj[key]
    })
    return newObj;
  }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值