学习

深浅拷贝

2019-07-16  本文已影响4人  感觉不错哦

什么是深浅拷贝就不解释了,一般情况下我们只需要浅拷贝来操作我们的对象,但是对象内还存在对象的话就需要深拷贝了。因为浅拷贝只拷贝指针,而深拷贝可以重新申请空间并将数据复制过来,我的理解就是无限浅拷贝(^_^

    let a = {
        age: 1
    }
    let b = a
    a.age = 2
    console.log(b.age) // 2

出现这种情况的原因很简单,因为变量b同时指向变量a的对象内存,改变a的同时b的获取内存对象也会发生改变

浅拷贝的实现

Object.assign

    let a = {
    age: 1
    }
    let b = Object.assign({}, a)
    a.age = 2
    console.log(b.age) // 1

展开运算符 ...

    let a = {
      age: 1
    }
    let b = { ...a }
    a.age = 2
    console.log(b.age) // 1

通常浅拷贝就能解决大部分问题了,但是当我们遇到如下情况就可能需要使用到深拷贝了

    let a = {
        age: 1,
        jobs: {
            first: 'FE'
        }
    }
    let b = { ...a }
    a.jobs.first = 'native'
    console.log(b.jobs.first) // native

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

这个问题通常可以通过 JSON.parse(JSON.stringify(object)) 来解决。

 let a = {
        age: 1,
        jobs: {
            first: 'FE'
        }
    }
    let b = JSON.parse(JSON.stringify(a))
    a.jobs.first = 'native'
    console.log(b.jobs.first) // FE

但是该方法也是有局限性的:

会忽略 undefined
会忽略 symbol
不能序列化函数
不能解决循环引用的对象

   let a = {
    age: undefined,
    sex: Symbol('male'),
    jobs: function() {},
    name: 'lwj'
  }
let b = JSON.parse(JSON.stringify(a))
console.log(b) // {name: "lwj"}

当然如果你会lodash一下就解决了

//写个方法

 function 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]) ? deepClone(obj[key]) : obj[key]
    })

    return newObj
    }

    let obj = {
    a: [1, 2, 3],
    b: {
        c: 2,
        d: 3
    }
}
let newObj = deepClone(obj)
newObj.b.c = 1
console.log(obj.b.c) // 2

仔细看还是能看懂的哈

Reflect.ownKeys可以理解成Object.getOwnPropertyNames(target) concat(Object.getOwnPropertySymbols(target)、

还是看代码吧

  var obj={}
  Object.defineProperties(obj,{
      values:{
          value:10,
          enumerable:false
      }
  })
  console.log(Object.keys(obj))//[] 空数组
  console.log(Reflect.ownKeys(obj))// values
JavaScript是一门面向对象的语言,对大部分人来说这只是一句口号,很多人都不理解这句话的涵义是什么,即:为什么称JavaScript是一门面向对象的语言。

JavaScript作为一门面向对象的语言,意味着我们不用全局定义函数去做操不同类型的值,数据类型本身可以定义方法(method)来使用值,例如,要对数组a中的元素进行排序,我们不必将a传入sort()函数,而是调用a的一个方法sort()。

    //面向过程
    function sort(arr){
    ... //将传入的数组进行排序
    return newArr
    }
    var a = [2,1,3]
    a = sort(a)
//--------------------------------------------
var a = [2,1,3]
a.sort() // [1,2,3]
上一篇 下一篇

猜你喜欢

热点阅读