深浅拷贝

作者: 感觉不错哦 | 来源:发表于2019-07-16 10:40 被阅读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]

相关文章

  • 2018-08-29

    深浅拷贝 1.根据拷贝内容的不同,分为深浅拷贝 深拷贝:内容...

  • js的深浅拷贝

    js的深浅拷贝可以分为数组的深浅拷贝和对象的深浅拷贝 一、数组的深浅拷贝如果只是简单的将数组中的元素付给另外一个数...

  • Python—浅拷贝与深拷贝

    浅拷贝 深拷贝 深浅拷贝的作用

  • 深浅拷贝

    先来了解一下这些:在js中变量类型基本分为两种:基本数据类型和引用数据类型;基本类型:Underfied Null...

  • 深浅拷贝

    浅拷贝是对一个对象的顶层拷贝。通俗的理解就是:拷贝了引用,并没有拷贝内容。 深拷贝是对于一个对象所有层次的拷贝(递...

  • 深浅拷贝

    深浅拷贝.copy 浅拷贝 这是一个方法,浅拷贝修改可变类型是会将原数据也一块修改 Copy.deepcopy 深...

  • 深浅拷贝

    1:is 和 ==的区别 is 是比较两个引用是否指向了同一个对象(地址引用比较)。== 是比较两个对象是否相等。...

  • 深浅拷贝

    函数的传递,与matlab不同,具有以下特点: 1.直接赋值会带来不同ID,例如,a=2,b=2 2.传递引用赋值...

  • 深浅拷贝

    最近一直被问到深浅拷贝的问题。自己也确实不太清楚怎么回事,现在来研究一下。 什么是深浅拷贝 浅拷贝:指针拷贝,不会...

  • 深浅拷贝

    概念: 浅复制:不拷贝对象本身,仅仅是拷贝指向对象的指针深复制:是直接拷贝整个对象内存到另一块内存中 注意:这里有...

网友评论

    本文标题:深浅拷贝

    本文链接:https://www.haomeiwen.com/subject/ghkzkctx.html