zoukankan      html  css  js  c++  java
  • JavaScript:利用递归实现对象深拷贝

    先来普及一下深拷贝和浅拷贝的区别
    浅拷贝:就是简单的复制,用等号即可完成

    
    let a = {a: 1}
    let b = a
    

    这就完成了一个浅拷贝
    但是当修改对象b的时候,我们发现对象a的值也被改变了

    
    b.a = 10
    console.log(a.a) => 10
    

    这是因为浅拷贝只复制了指向对象的指针,新旧对象共用同一块内存,修改某一个对象的同时也会把另一个都一并修改了

    深拷贝:跟浅拷贝最简单明了的区别就是修改拷贝的对象,不会改变源对象
    利用Object.assign可以对只有一层的对象实现深拷贝,如下:

    
    let a = {a: 1,b: 2,c: 3}
    let b = Object.assign({}, a)
    b.b = 100
    console.log(a.b) => 2
    

    可以看出来这样是完全可以做到对只有一层的对象实现深拷贝的
    但是如果对象里面的元素还是对象的话就没作用了

    
    let a = {a: 1,b: 2,c: 3, d: {a: 1}}
    let b = Object.assign({}, a)
    b.d.a = 100
    console.log(a.d.a) => 100
    

    对于这种比较复杂的对象,我们就可以利用递归的方式实现真正的对象深拷贝了

    
    function deepClone (sourceObj, targetObj) {
        let cloneObj = targetObj || {}
        if(!sourceObj || typeof sourceObj !== "object" || sourceObj.length === undefined){
            return sourceObj
        }
        for(let i in sourceObj){
            if (typeof sourceObj[i] === 'object' && sourceObj[i].length !== undefined) {
                cloneObj[i] = deepClone(sourceObj[i], {})
            } else {
                cloneObj[i] = sourceObj[i]
            }
        }
        return cloneObj
    }
    

    简单的几行代码就可以轻松实现对象的深拷贝

    
    简单的测试代码,如下:
    let sourceObj = {
      a: 1,
      b: {
        a: 1
      },
      c: {
        a: 1,
        b: {
          a: 1
        }
      },
      d: function() {
        console.log('hello world')
      },
      e: [1, 2, 3]
    }
    let targetObj = deepClone(sourceObj, {})
    targetObj.c.b.a = 9
    console.log(sourceObj) => { a: 1,  b: { a: 1 },  c: { a: 1, b: { a: 1 } },  d: [Function: d],  e: [ 1, 2, 3 ] }
    console.log(targetObj) => { a: 1,  b: { a: 1 },  c: { a: 1, b: { a: 9 } },  d: [Function: d],  e: [ 1, 2, 3 ] }
    

    另外介绍两个用来做深拷贝的库

    
    **jquery**
    使用方法:
    let targetObj = $.extent(true,{},sourceObj)
    **lodash函数库**
    使用方法:
    npm install lodash
    **es5写法**
    let lodash = require('lodash')
    **es6写法**
    import lodash from 'lodash'
    
    let targetOj = lodash.cloneDeep(sourceObj)
    

    各位看官觉得有什么地方不对的请多多指教。

    来源:https://segmentfault.com/a/1190000015924675

  • 相关阅读:
    GitLab 介绍
    git 标签
    git 分支
    git 仓库 撤销提交 git reset and 查看本地历史操作 git reflog
    git 仓库 回退功能 git checkout
    python 并发编程 多进程 练习题
    git 命令 查看历史提交 git log
    git 命令 git diff 查看 Git 区域文件的具体改动
    POJ 2608
    POJ 2610
  • 原文地址:https://www.cnblogs.com/lovellll/p/10180109.html
Copyright © 2011-2022 走看看