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


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. 解决windows8.1的依赖

  2. Redis安装过程:

  3. Spring MVC 返回 xml json pdf 数据的配置方法

    <!-- Spring MVC 返回 xml 数据的配置方法 -->     <bean class="org.springframework.web.servlet.vi ...

  4. [转]WPF中的ControlTemplate(控件模板)

    WPF中的ControlTemplate(控件模板)                                                                           ...

  5. Joomla - akeeba backup(joomla网站备份、迁移扩展)

    在所有 joomla 的网站中,如果只允许安装一个扩展,估计超过90%的人都会选择 akeeba backup,这基本是每个joomla都必备的一个扩展: akeeba backup 的更多资料可以到 ...

  6. PHP--通用化API接口数据输出 封装

    /** * 通用化API接口数据输出 * author qinpeizhou * @param $message * @param array $data * @param int $httpCode ...

  7. alert提示框去掉域名

    window.alert = function(name){ var iframe = document.createElement("IFRAME"); iframe.style ...

  8. hibernate一对多关系 在一方查询会获得重复数据,重复数量就是多端数据数量用@Fetch(FetchMode.SUBSELECT)解决

    先来看数据表 版块表只有两个数据 板块1是推荐,下边没有子栏目 板块2下边有14个子栏目 在1的一端来查询,发现结果有16条 也就是板块1+版块2+版块2和他的14个子集都列出来了,这明显不对 板块对 ...

  9. Linux 系统的运行级别(runlevel)

    Linux 系统有 7 个运行级别,Linux 系统任何时候都运行在一个指定的运行级别上,不同的运行级别所运行的程序和服务不尽相同,所要完成的工作和要达到的目的也不相同 · 运行级别 0 系统停机(h ...

  10. Leetcode90. Subsets II子集2

    给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集). 说明:解集不能包含重复的子集. 示例: 输入: [1,2,2] 输出: [ [2], [1], [1,2,2], [2 ...