js深浅拷贝

作为一枚前段,我们知道对象类型在赋值的过程中其实是复制了地址,从而会导致改变了一方其他也都被改变的情况。通常在开发中我们不希望出现这样的问题,我们可以使用浅拷贝来解决这个情况。

浅拷贝

首先可以通过Object.assign来解决这个问题,很多人认为这个函数是用来深拷贝的。其实并不是,Object.assign只会拷贝所有的属性值到新的对象中,如果属性值是对象的话,拷贝的是地址,所以并不是深拷贝。

1 let abc = {
2     a: '123',
3     b: 'aaa',
4     d: 'cccc'
5 }
6 let b = Object.assign({}, abc)
7 abc.a = '222'
8 console.log(b.a) // 123

另外还可通过es6的运算符来. .. 来实现

1 let obj = {
2     age: '23',
3     name: 'chai'
4 }
5 let newobj = {...obj}
6 obj.age = '17'
7 console.log(newobj.age) // 23

浅拷贝只解决了第一层的问题,如果接下去的值中还有对象的话,那么就又回到最开始的话题了,两者享有相同的地址。要解决这个问题,我们就得使用深拷贝了。

浅拷贝

通常可以通过JSON.parse(JSON.stringify(object))来解决

1 let a = {
2   age: 1,
3   jobs: {
4     first: 'FE'
5   }
6 }
7 let b = JSON.parse(JSON.stringify(a))
8 a.jobs.first = 'native'
9 console.log(b.jobs.first) // FE

平时就这几种方法就够使用了,深拷贝这种方法也是有局限性的,它会忽略undefined,symble,不能序列化函数,如

1 let a = {
2   age: undefined,
3   sex: Symbol('male'),
4   jobs: function() {},
5   name: 'vue'
6 }
7 let b = JSON.parse(JSON.stringify(a))
8 console.log(b) // {name: "vue"}

 最优的也是建议的一种浅拷贝

const _shallowClone = target => {
  // 基本数据类型直接返回
  if (typeof target === 'object' && target !== null) {
    // 获取target 的构造体
    const constructor = target.constructor
    // 如果构造体为以下几种类型直接返回
    if (/^(Function|RegExp|Date|Map|Set)$/i.test(constructor.name)) return target
    // 判断是否是一个数组
    const cloneTarget = Array.isArray(target) ? [] : {}
    for (prop in target) {
      // 只拷贝其自身的属性
      if (target.hasOwnProperty(prop)) {
        cloneTarget[prop] = target[prop]
      }
    }
    return cloneTarget
  } else {
    return target
  }
}

  

posted @ 2019-03-02 16:12  府谷市民小柴  阅读(299)  评论(0编辑  收藏  举报