JavaScript对象深拷贝

引言

在JavaScript中对对象拷贝复制通常是使用循环遍历的方式:

var obj = {x:1,y:[1,2,3]
}var obj2 = {};
for(let key in obj){obj2[key] = obj[key];
}obj.x = 10;
obj.y[0] = 4;
console.log(obj,obj2);


虽然obj2和obj输出的结果看起来是一样的,但当obj.y发生改变,obj2也会改变,因为引用类型赋值的是地址,这种复制方式一般称为浅拷贝。那么如何实现深度拷贝呢?下面介绍几种JavaScript中常见的深拷贝的方式。

一、序列化、反序列化

通过JSON.parse和JSON.stringify

var obj = {x:1,y:[1,2,3]
}var obj2 = JSON.parse(JSON.stringify(obj)); // 先转为json字符串,再转回对象obj.x = 10;
obj.y[0] = 4;
console.log(obj,obj2);


但是通过JSON复制有一定的局限性,对象中的值value的数据类型为undefined、function和symbol时直接被忽略。

var obj = {a:1,b:[1,2,3],c:undefined,d:function (){console.log(1);},e:Symbol()
}
var obj2 = JSON.parse(JSON.stringify(obj));
console.log(obj,obj2);

二、递归实现深拷贝

面试题:深拷贝如何实现?

// 定义判断数据类型的函数
function getClass(obj){return Object.prototype.toString.call(obj).slice(8,-1);
}function deepCopy(obj){var result,oclass = getClass(obj);// 判断传入obj是否是引用类型if(oclass == 'Object') result = {};else if(oclass == 'Array')  result = [];else return obj;// 遍历对象for(let key in obj){ var copy = obj[key];if(getClass(copy) == 'Object'||getClass(copy) == 'Array'){result[key] = deepCopy(copy); // 再次调用函数// result[key] = arguments.callee(copy);} else {result[key] = copy;}}return result;
}
var obj = {a:1,b:[1,2,3],c:undefined,d:function (){console.log(1);},e:Symbol()
}
var obj2 = deepCopy(obj);obj.a = 10;
obj.b[0] = 4;
console.log(obj,obj2);

三、通过使用第三方工具库–jQuery

var obj = {a:1,b:[1,2,3],c:undefined,d:function (){console.log(1);},e:Symbol()
}var obj2 = $.extend(true,{},obj);
// jQuery.extend([deep],target,object1[,objectN])
// true设置为深拷贝,false是默认值为浅拷贝obj.a = 10;
obj.b[0] = 4;
console.log(obj,obj2);

四、通过第三方工具库–lodash

使用_.cloneDeep(value)函数,它会递归拷贝value(深拷贝)

var objects = [{ 'a': 1 }, { 'b': 2 }];var deep = _.cloneDeep(objects); // 返回拷贝后的值
console.log(deep[0] === objects[0]);
// => false

五、使用immutable.js-----性能最高

六、通过Object.create()/Object.assign()–浅拷贝

Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。
Object.assign()方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。

var obj = {a: 1,b: [1, 2, 3],c: undefined,d: function () {console.log(1);},e: Symbol()
}var obj2 = Object.create(obj); // 使用继承的方式
// 同理,使用Object.assign()
var obj3 = {};
Object.assign(obj3, obj);obj.a = 10;
obj.b[0] = 4;console.log(obj, obj2, obj3);


但是这两种方法都只对一层的对象有效

JavaScript对象深拷贝相关推荐

  1. 详解JavaScript对象深拷贝

    详解JavaScript对象深拷贝 在几乎所有编程语言中,对象都以引用形式保存给变量.复制给其他变量.JavaScript语言也是如此.因此简单的进行赋值操作进行复制仅仅是对对象数据的引用地址进行一个 ...

  2. 一维数组与对象深拷贝的几种方法(指数组、对象中均无嵌套)

    一.万能for循环 直接上代码: var arr = [1, 2, 3, 4, 5]var obj = { name: "aaaaa", age: 16 }var arr2 = c ...

  3. js复制html样式,js对象深拷贝的方法

    js 怎么把对象深拷贝到另一个对象 buy:function(buyList){buyList.forEach(function(good){good.farmer=this;});},buy是Far ...

  4. 如何获取HTML元素对应JavaScript对象?

    <!DOCTYPE html> <html><head><meta charset="UTF-8"><title>< ...

  5. JavaScript对象,方括号和算法

    by Dmitri Grabov 德米特里·格拉波夫(Dmitri Grabov) JavaScript对象,方括号和算法 (JavaScript Objects, Square Brackets a ...

  6. 我对javascript对象的理解

    前言 JavaScript这门语言除了基本类型都是对象,可以说JavaScript核心就是对象,因此理解JavaScript对象及其种种特性至关重要,这是内功.本文介绍了我对es5对象,原型, 原型链 ...

  7. 《JavaScript启示录》——1.21 JavaScript对象和Object()对象

    本节书摘来自异步社区<JavaScript启示录>一书中的第1章,第1.21节,作者:[美]Cody Lindley著,更多章节内容可以访问云栖社区"异步社区"公众号查 ...

  8. java map to map 拷贝_java复制Map 对象(深拷贝和浅拷贝)

    java复制Map 对象(深拷贝和浅拷贝) java复制Map 对象(深拷贝和浅拷贝) 2. 通过 putAll()方法能实现浅拷贝和深拷贝, 使用Map对象只能实现浅拷贝 public static ...

  9. 《JavaScript启示录》——第1章 JavaScript对象 1.1创建对象

    本节书摘来自异步社区<JavaScript启示录>一书中的第1章,第1.1节,作者:[美]Cody Lindley著,更多章节内容可以访问云栖社区"异步社区"公众号查看 ...

最新文章

  1. 领域驱动设计系列文章汇总
  2. Elasticsearch索引迁移的三种方式
  3. Asp.net Core全局异常监控和记录日志
  4. c语言课设报告时钟vc环境,C语言课程设计报告模拟时钟转动程序
  5. char *p = new char[256]; delete p; / delete[] p; 哪个对 为什么
  6. springboot中的controller注解没有生效
  7. android手机导入.cer证书文件的方法
  8. [译]写给初学者的Tensorflow介绍 - 2
  9. openbsd_仔细看一下OpenBSD
  10. 转 Oracle 9i,10g,11g各自alert日志的位置
  11. linux驱动程序的测试,Linux驱动学习笔记(4)字符设备驱动测试
  12. 阿里云申请和部署项目
  13. (内含两种方式)Android 在线查看文档world丶xls丶ppt等文件
  14. kettle 邮件服务器,kettle 实用功能之三 ---- 使用 kettle 群发动态内容的邮件。
  15. 基于javaweb的宠物医院预约管理系统设计和实现(java+springboot+mysql+ssm)
  16. 135、易燃液体的火灾危险性
  17. Python爬虫实战——反爬机制的解决策略【阿里】
  18. 错误记录一:线程通信时抛出Exception in thread “Thread-0” java.lang.IllegalMonitorStateException异常
  19. C语言小例子【基础】
  20. php全套之七,【独家首发】最新七星修改二开正米酷影视7.2完整版/支持自定义解析/支持PHP7.0及以上...

热门文章

  1. linux 安装git客户端
  2. 进程同步与互斥——哲学家就餐问题源码实现(dining philosopher’s problem)
  3. 年薪30万的 iOS开发者自述:“幸亏我被裁员了”
  4. IO复用的总结及一些问题
  5. 扫雷TigerMinesweeper_01
  6. 假设市面上有4种面值 硬币,20元、10元、5元、1元。输入一个钱数,能够使用最少的硬币凑成这个钱数
  7. 别在折腾开发环境了,一劳永逸的 Python 环境搭建方法
  8. CSS图片水平垂直居中的三种方法
  9. c语言以空格分割字符串_C语言strtok()函数:用指定的分隔符分解字符串
  10. 无线局域网的嗅探攻击和防御——ettercap+driftnet