js 对象深复制(深拷贝)
对象深复制
复制逻辑
什么是深复制和浅复制?JavaScript有6种基本数据类型(Number,Boolean,String、null、udefined和Symbol)和1种引用类型(Object)。
- 基本数据类型自身变量所指的内存,存的就是自身的值(String例外)
- 引用数据类型存的是个引用地址(指针),具体数据存在堆中。
- String在JavaScript比较特殊,它虽然是基本数据类型,但它却是按照引用类型在使用。 对于基本值类型(String)除外,直接复制,要想实现深复制,只要遇到引用类型,必须用new的方式重新创建,并且被复制对象的内部属性,如果是引用,也要这么处理。对象的属性有很多层,这就是深复制实现复杂的原因。
代码实现
首先我们创建一个对象来进行测试var d = Symbol();var e = Symbol();var ss = { a: 1 };var obj = {a: 1,b: 2,c: [1, 2, 3],zz: new Set([1, 2, ss]),yy: new Map(),[d]: "aaa",z: document.createElement("div"),d: {e: new Date(),f: /a/g,g: function (s) {console.log(s);},h: {},},};Object.defineProperties(obj.d.h, {i: {value: 10,},j: {configurable: true,writable: true,value: [1, 2, 3, 4],},k: {writable: true,value: {l: {},m: "abcde",n: true,o: [1, 2, 3],},},[e]: {value: ["a", "b", "c", "e"],},});Object.defineProperties(obj.d.h.k.l, {p: {value: function () {console.log("p");},},q: {value: {r: { a: 1 },j: { b: 2 },},},});var a_1 = { a: 1 };var a_2 = { b: 2 };obj.yy.set("name", "xietian");obj.yy.set(a_1, a_2);//对象深复制
const cloneObject = (source, target) => {if (source === null || source === undefined) return source; //判断非空非undefined// if (source === document) return; //非documentif (!Object.prototype.isPrototypeOf(target)) { //target是否已经存在对象原型上if (HTMLElement.prototype.isPrototypeOf(source)) { //HTML复制target = document.createElement(source.nodeName);} else if (source.constructor === RegExp) { //RegExp复制target = new RegExp(source.source, source.flags);} else if (source.constructor === Date) { //Date复制target = new Date(source);} else if (source.constructor === Function) { //Function 复制var arr = source.toString().replace(/\n|\r/g, "").trim().match(/\((.*?)\)\s*\{(.*)\}/).slice(1); //进行source处理target = new Function(arr[0].trim(), arr[1]);} else if (source.constructor === Set) { //Set复制target = new Set(cloneObject(Array.from(source.values())))} else if (source.constructor === Map) { // Map复制target = new Map();// entries() 方法返回一个数组的迭代对象,该对象包含数组的键值对 (key/value)。// 迭代对象中数组的索引值作为 key,数组元素作为 value。for (var [key, value] of source.entries()) { //解构赋值if (Object.prototype.isPrototypeOf(key)) { //判断Map中的key和value类型进行后续复制处理 引用类型继续cloneif (Object.prototype.isPrototypeOf(value)) {target.set(cloneObject(key), cloneObject(value));} else {target.set(cloneObject(key), value);}} else {if (Object.prototype.isPrototypeOf(value)) {target.set(key, cloneObject(value));} else {target.set(key, value);}}}} else {target = new source.constructor(); //判断完毕后 剩下的数组和对象等 直接new一个source类型}}//getOwnPropertyNames方法返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组。getOwnPropertySymbols返回symbol的值var names = Object.getOwnPropertyNames(source).concat(Object.getOwnPropertySymbols(source));for (var i = 0; i < names.length; i++) {// console.log(names[i]);if (source.constructor === Function && names[i] === "prototype") continue; //函数会比较特殊 在这进行判断函数var desc = Object.getOwnPropertyDescriptor(source, names[i]);if (Object.prototype.isPrototypeOf(desc.value)) { //函数会因为它的prototype constructor指向的是一个函数 然后函数继续指向函数 所以会死循环// 根据需要将源对象的描述内容设置给当前目标对象// 相同属性名的描述内容,及值赋为刚才创建相同类型的对象Object.defineProperty(target, names[i], {enumerable: desc.enumerable,configurable: desc.configurable,writable: desc.writable,value: cloneObject(desc.value)});} else {// 如果描述的对象的值不是引用类型,// 直接将描述对象设置给目标对象的这个属性Object.defineProperty(target, names[i], desc);}}return target;
}// a_1.a = 100;
// obj.d.h.j[1] = 1000;
const _obj = cloneObject(obj);
console.log(_obj);
js 对象深复制(深拷贝)相关推荐
- JS对象拷贝:深拷贝和浅拷贝
摘要:对象拷贝,简而言之就是将对象再复制一份,但是,复制的方法不同将会得到不同的结果. 本文分享自华为云社区<js对象深浅拷贝,来,试试看!>,作者: 北极光之夜.. 一.速识概念: 对象 ...
- js对象浅拷贝与深拷贝
一.简介 浅拷贝是拷贝一层,如果数据是基本数据类型,会拷贝其本身,如果除了基本数据类型之外还有一层对象,那么只能拷贝其引用,对象的改变会反应到拷贝对象上. 深拷贝是拷贝多层,每一层的数据都 ...
- 一行代码完成js对象数组的深拷贝
1.对于普通数组(数组元素为数字或者字符串),深拷贝很简单,拷贝之后两个数组指针指向的存储地址不同,从而完成深拷贝 var _test = [1,2,3];//原数组 var _testCopy = ...
- js对象、数字深拷贝方式(转)
知识点一:js中的对象 谈到对象的拷贝,必定要说一下对象的概念.js中的数据类型分为两大类:原始类型和对象类型.(1)原始类型包括:数值.字符串.布尔值.null.undefined(后两个是特殊的原 ...
- js 对象浅拷贝和深拷贝
var model={name:"boy",age:13}; var CopyModel=model; console.log(CopyModel.name); model.nam ...
- JavaScript中对象深复制
参考: http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/ 本文转自 ...
- JavaScript 复制对象与Object.assign方法无法实现深复制
在JavaScript这门语言中,数据类型分为两大类:基本数据类型和复杂数据类型.基本数据类型包括Number.Boolean.String.Null.String.Symbol(ES6 新增),而复 ...
- C++深复制(深拷贝)、浅复制(浅拷贝)和复制构造函数(拷贝构造函数)详解+实例
转载出处:https://blog.csdn.net/sxhelijian/article/details/23209967 对象的复制 对于普通类型的对象来说,它们之间的复制是很简单的,例如: in ...
- Copy(定义,特点,深复制,浅复制)(非ARC,ARC的运用范围)
什么是copy? Copy的字面意思是"复制","拷贝",是一个产生副本的过程. 作用:利用一个源对象产生一个副本对象. 特点: 1,修改源对象的属性和行为,不 ...
最新文章
- python从list列表中选出一个数和其对应的坐标
- OpenCvSharp中CV_8UC1,CV_8UC2等参数的解释
- 聚类之K-means均值聚类
- static在内存层面的作用_static的作用和内存划分?
- QT的QTreeWidgetItem类的使用
- navicat 导入SQL文件出错
- cad万能字体_CAD图纸问号“?”的处理
- java 面向对象继承的思想_Java面向对象思想!
- 用Layer.search快速查询图元
- Linux 命令(52)—— ipcrm 命令
- 边缘检测算法_机器视觉怎样检测产品边缘
- 定义一个内核panic问题
- Python正则表达式去除符号
- SAP中通过删除新建未记账成本要素期间的方式更改成本要素类别
- 如何为计算机设置ip地上,电脑ip地址设置为多少
- 视频分辨率过高,导致部分手机播放失败
- AppLocker绕过之路
- matlab限幅器无饱和怎么设置,基于MATLAB 的直流电动机双闭环调速系统的仿真研究...
- 人脸识别考勤系统解决方案
- 不可小觑的吃内存大户