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


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

JavaScript:利用递归实现对象深拷贝的更多相关文章

  1. JavaScript递归实现对象深拷贝

    let personOne = { name:"张三", age:18, sex:"male", children:{ first:{ name:"z ...

  2. javascript 利用匿名函数对象给你异步回调方法传参数

    先来创建一个匿名函数对象: /*** * 匿名函数 */ var callChangeBtn=new function(bugBtn){ this.chage=function(json){ bugB ...

  3. JavaScript利用递归和循环实现阶乘

    [实现方法] 1.利用while循环来做,当然for循环也可以. 2.递归 [代码内容] 偷懒,直接用onkeyup事件来限制来页面的输入 循环代码: //第一种方法 while循环 oCount.o ...

  4. javascript JS递归遍历对象 使用for(variable in object)或者叫for/in和forEach方式

    1.递归遍历查找特定key值(ie9以下不支持forEach) 原文http://www.cnblogs.com/ae6623/p/5938560.html var obj = { first: &q ...

  5. Javascript利用递归实现数组的快速排序

    // 定义快速排序方法 function quickSort(arr){ // 设置递归的终止条件 if( arr.length <= 1){ return arr; } // 获得数组arr的 ...

  6. javascript对象深拷贝,浅拷贝 ,支持数组

    javascript对象深拷贝,浅拷贝 ,支持数组 经常看到讨论c#深拷贝,浅拷贝的博客,最近js写的比较多, 所以也来玩玩js的对象拷贝. 下面是维基百科对深浅拷贝的解释: 浅拷贝 One meth ...

  7. javascript学习总结之对象的深拷贝和浅拷贝

    前言 最近在写ES6的文章的时候发现重复遇到关于javascript深拷贝和浅拷贝的问题,然后查找了一些资料,根据资料和自己的理解做了以下笔记,毕竟javascript关于深拷贝和浅拷贝的问题在一些面 ...

  8. JavaScript对象---递归遍历对象

    JavaScript 中的所有事物都是对象:字符串.数值.数组.函数... 此外,JavaScript 允许自定义对象. JavaScript 对象 JavaScript 提供多个内建对象,比如 St ...

  9. JavaScript的 基本数据类型---对象

    第一:Javascript对象是 第二:Javascript中 第三:Javascript的对象是数据: 第四:JavaScript 中的对象可以简单理解成"名称:值"对(name ...

随机推荐

  1. Leetcode944. Delete Columns to Make Sorted删列造序

    给定由 N 个小写字母字符串组成的数组 A,其中每个字符串长度相等. 选取一个删除索引序列,对于 A 中的每个字符串,删除对应每个索引处的字符. 所余下的字符串行从上往下读形成列. 比如,有 A = ...

  2. centos Python2.6 升级到2.7

    需求: centos 6.x 系统默认Python 版本都是2.6,实际生产环境中需要用到Python 2.7.x Python 2.7 下载地址 [root@ansible package]# wg ...

  3. 使用由 Python 编写的 lxml 实现高性能 XML 解析

    lxml 简介 Python 从来不出现 XML 库短缺的情况.从 2.0 版本开始,它就附带了 xml.dom.minidom 和相关的 pulldom 以及 Simple API for XML ...

  4. Laravel报错:1071 Specified key was too long; max key length is 1000 bytes

    Laravel安装,初始化数据库,运行下列命令时候出错 php artisan migrate 解决办法1,设置数据库引擎格式 //临时更改 SET GLOBAL default_storage_en ...

  5. Linux 内存缓存占用过大,Centos7设置定时清除buff/cache的脚本

    Linux系统buff/cache 中缓存数据占用内存过高,定时清理buff/cache ,释放系统内存 root权限创建脚本文件: touch cleanCache.sh && vi ...

  6. 转: V4L2驱动程序架构

    源地址:http://blog.chinaunix.net/uid-26101960-id-3297657.html 1 V4L2简介 video4linux2(V4L2)是Linux内核中关于视频设 ...

  7. 转载 Python 安装setuptools和pip工具操作方法(必看)

    本文章转载自 脚本之家 http://www.jb51.net  感谢! setuptools模块和pip模块是python进行第三方库扩展的极重要工具,例如我们在需要安装一些爬虫或者数据分析的包时就 ...

  8. 009-python一些问题整理

    1. Python中的 // 与 / 的区别 " / "  表示浮点数除法,返回浮点结果 >>> 90/30 3.0 " // " 表示整数除 ...

  9. Maven入门指南:仓库

    1 . 仓库简介 没有 Maven 时,项目用到的 .jar 文件通常需要拷贝到 /lib 目录,项目多了,拷贝的文件副本就多了,占用磁盘空间,且难于管理.Maven 使用一个称之为仓库的目录,根据构 ...

  10. 2019.10.29 csp-s模拟测试92 反思总结

    今天快乐的墨雨笙因为什么而几乎爆零了呢? 顾此失彼+不会对拍+无脑的复杂度 今天高兴的墨雨笙又因为什么调了一个下午呢? 不明题意+不想范围+板子低级错误 R.I.P. T1: //唉 //害怕TLE, ...