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
JavaScript:利用递归实现对象深拷贝的更多相关文章
- JavaScript递归实现对象深拷贝
let personOne = { name:"张三", age:18, sex:"male", children:{ first:{ name:"z ...
- javascript 利用匿名函数对象给你异步回调方法传参数
先来创建一个匿名函数对象: /*** * 匿名函数 */ var callChangeBtn=new function(bugBtn){ this.chage=function(json){ bugB ...
- JavaScript利用递归和循环实现阶乘
[实现方法] 1.利用while循环来做,当然for循环也可以. 2.递归 [代码内容] 偷懒,直接用onkeyup事件来限制来页面的输入 循环代码: //第一种方法 while循环 oCount.o ...
- 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 ...
- Javascript利用递归实现数组的快速排序
// 定义快速排序方法 function quickSort(arr){ // 设置递归的终止条件 if( arr.length <= 1){ return arr; } // 获得数组arr的 ...
- javascript对象深拷贝,浅拷贝 ,支持数组
javascript对象深拷贝,浅拷贝 ,支持数组 经常看到讨论c#深拷贝,浅拷贝的博客,最近js写的比较多, 所以也来玩玩js的对象拷贝. 下面是维基百科对深浅拷贝的解释: 浅拷贝 One meth ...
- javascript学习总结之对象的深拷贝和浅拷贝
前言 最近在写ES6的文章的时候发现重复遇到关于javascript深拷贝和浅拷贝的问题,然后查找了一些资料,根据资料和自己的理解做了以下笔记,毕竟javascript关于深拷贝和浅拷贝的问题在一些面 ...
- JavaScript对象---递归遍历对象
JavaScript 中的所有事物都是对象:字符串.数值.数组.函数... 此外,JavaScript 允许自定义对象. JavaScript 对象 JavaScript 提供多个内建对象,比如 St ...
- JavaScript的 基本数据类型---对象
第一:Javascript对象是 第二:Javascript中 第三:Javascript的对象是数据: 第四:JavaScript 中的对象可以简单理解成"名称:值"对(name ...
随机推荐
- commons-httpclient和org.apache.httpcomponents的区别
<dependency> <groupId>commons-httpclient</groupId> <artifactId>commons-httpc ...
- 2019-4-16-C#-使用反射获取私有属性的方法
title author date CreateTime categories C# 使用反射获取私有属性的方法 lindexi 2019-4-16 10:13:3 +0800 2018-09-26 ...
- [转]Visual Studio 2010单元测试(3)--顺序单元测试
之前我们做的测试都是一个一个进行的,当然我们也可以一次性选择多个测试方法进行,但是测试运行的顺序以“测试列表编辑器”窗口中的默认列表顺序为准.在实际场景中,我们需要进行有顺序的单元测试,步骤可能每一步 ...
- [编织消息框架][netty源码分析]3 EventLoop 实现类SingleThreadEventLoop职责与实现
eventLoop是基于事件系统机制,主要技术由线程池同队列组成,是由生产/消费者模型设计,那么先搞清楚谁是生产者,消费者内容 SingleThreadEventLoop 实现 public abst ...
- Flink 1.9 实战:使用 SQL 读取 Kafka 并写入 MySQL
上周六在深圳分享了<Flink SQL 1.9.0 技术内幕和最佳实践>,会后许多小伙伴对最后演示环节的 Demo 代码非常感兴趣,迫不及待地想尝试下,所以写了这篇文章分享下这份代码.希望 ...
- Django项目:CRM(客户关系管理系统)--61--51PerfectCRM实现CRM客户报名流程学生合同上传照片
# sales_views.py # ————————47PerfectCRM实现CRM客户报名流程———————— from django.db import IntegrityError # 主动 ...
- angular路由配置以及使用
一.生成路由文件 按照惯例,有一个独立模块来配置相关路由,这个模块类的名字叫做AppRoutingModule,位于src/app下的app-routing.module.ts文件中. 使用CLI生成 ...
- Spring注解驱动开发(三)-----自动装配
自动装配 概念 Spring利用依赖注入(DI),完成对IOC容器中中各个组件的依赖关系赋值. @Autowired-----自动注入 1.默认优先按照类型去容器中找对应的组件 application ...
- CCS开发指南
第一章 CCS概述 1 1.1 CCS概述 1 1.2 代码生成工具 3 1.3 CCS集成开发环境 5 1.3.1 编辑源程序 5 1.3.2创建应用程序6 1.3.3 调试应用程序 6 1.4 ...
- 文件上传 - Commons FileUpload介绍
概述 FileUpload能够以多种不同的方式使用,具体取决于应用程序的要求.在最简单的情况下,调用单个方法来解析servlet请求,然后处理解析出来的Item集合.此外也可以自定义FileUploa ...