js对象克隆
大家都知道,js的对象是引用类型,如果直接var obj2 = obj,obj2和obj是共享同一个对象实体的,这往往不是我们想要的结果。
官方并没有给出通用的对象克隆方法:
我们给出以下几种写法:
1.通用对象克隆:
function clone(obj, hash = new WeakMap()) {
// 解决循环引用
if (hash.has(obj)) {
return hash.get(obj)
}
let temp = null;
if (obj instanceof Array) {
// 特殊处理数组对象类型
temp = []
hash.set(obj, temp)
obj.forEach(item => {
temp.push(clone(item, hash));
})
} else if (obj instanceof RegExp) {
// 特殊处理正则对象类型
const { source, global, ignoreCase, multiline } = obj;
let flags = '';
if (global) flags += 'g';
if (ignoreCase) flags += 'i';
if (multiline) flags += 'm';
temp = new RegExp(source, flags);
} else if (obj instanceof Date) {
// 特殊处理时间对象类型
temp = new Date(obj.getTime());
} else if (typeof obj === 'object') {
// 处理普通对象类型
// 以obj的原型为原型,构造一个新对象
temp = Object.create(obj.__proto__);
hash.set(obj, temp)
} else {
temp = obj;
}
// 任何对象类型,都遍历递归自身的属性
if (typeof obj === 'object') {
for (let [key, val] of Object.entries(obj)) {
temp[key] = clone(val, hash);
}
}
return temp;
}
遇到数组对象类型、正则对象类型、时间对象类型、普通对象类型都需要有自己的特殊,最后他们都需要遍历递归他们自身的属性
原始类型(包括Symbol)纯复制就可以了
函数做的浅拷贝(因为如果拷贝函数,只能用eval这个危险的工具了,所以这里函数仅作浅克隆,lodash的cloneDeep对函数也是浅克隆处理)
推荐阅读:https://juejin.im/post/5b235b726fb9a00e8a3e4e88
ps:这里还有一些坑,无法克隆 Error 对象,无法克隆原型,无法克隆不可枚举的属性.... 不过这个深克隆已经可以覆盖百分之99的场景了!!
2.JSON对象序列化方法
深拷贝,但是有一大堆坑(推荐阅读:https://juejin.im/post/5abb55ee6fb9a028e33b7e0a):
基础的5个大坑:
1. 函数不能拷贝
2. Symbol不能拷贝
4. undefined不能拷贝
5. 正则拷贝后变成普通对象
6. 循环引用的对象会报错
7. 数组的属性丢失
8. 数组里面的undefined会变成null
9. 会抛弃对象的constructor
。。。。估计还有很多我没想到的
let a = { age: undefined, sex: Symbol('male'), jobs: function() {}, name: 'yck' }
let b = JSON.parse(JSON.stringify(a)) console.log(b) // {name: "yck"}
正常使用:
var obj = {a:1,b:2}
var newObj = JSON.parse(JSON.stringify(obj));
3.dom元素的复制——cloneNode
let div = document.getElementById('box');
let box2 = div.cloneNode(true);
4.es6新方法——Object.assign
浅拷贝
var obj = {a:1,b:2}
var newObj = Object.assign({}, obj);
5. MessageChannel的方法
异步的深克隆,但是无法克隆function 、Symbol
let obj = {a: 1,b: 2}
let {port1, port2} = new MessageChannel();
port2.onmessage = ev => console.log(ev.data)
port2.postMessage(obj)
总结:日常使用还是推荐用lodash的cloneDeep
js对象克隆的更多相关文章
- js 对象克隆方法总结(不改变原对象)
1.通用对象克隆: function clone(obj){ let temp = null; if(obj instanceof Array){ temp = obj.concat(); }else ...
- js对象克隆, 深复制.
亲测有效: //对象克隆 function clone(obj) { // Handle the 3 simple types, and null or undefined if (null == o ...
- js对象克隆方法
方法1: function clone(obj){ var o; switch(typeof obj){ case 'undefined': break; case 'string' : o = ob ...
- js对象的深度克隆
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- js深度克隆对象
js深度克隆对象 js深度克隆对象简单的记录一下,如下代码: var obj = { typeOf: function(obj) { const toString = Object.prototype ...
- js对象简单、深度克隆(复制)
javascript的一切实例都是对象,只是对象之间稍有不同,分为原始类型和合成类型.原始类型对象指的是字符串(String).数值(Number).布尔值(Boolean),合成类型对象指的是数组( ...
- JS对象复制
在JavaScript很多人复制一个对象的时候都是直接用"=",因为大家都觉得脚本语言是没有指针.引用.地址之类的,所以直接用"="就可以把一个对象复制给另外一 ...
- js对象详解(JavaScript对象深度剖析,深度理解js对象)
js对象详解(JavaScript对象深度剖析,深度理解js对象) 这算是酝酿很久的一篇文章了. JavaScript作为一个基于对象(没有类的概念)的语言,从入门到精通到放弃一直会被对象这个问题围绕 ...
- 原型模式和基于原型继承的js对象系统
像同样基于原型编程的Io语言一样,javascript在原型继承方面,实现原理和Io非常类似,javascript也遵守这些原则 所有数据都是对象 要得到一个对象,不是通过实例化类,而是找到一个对象作 ...
随机推荐
- Activiti中子流程:SubProcess,CallActiviti的区别
子流程:SubProcess,CallActiviti的区别 https://community.alfresco.com/thread/221771-call-activiti-vs-subproc ...
- XMLHttpRequest详解
XMLHttpRequest详解: https://xhr.spec.whatwg.org/
- 关于Http_build_query的用法
使用背景:在做接口业务过程中,有时会遇到这种情况,本地APP需要接口给其返回一个url,那么在拼接参数的时候,用这个函数就会很方便. 百度百科上给的解释是这样的:http_build_query -- ...
- 一个本科学生对Linux的认知
我是一名大三的普通一本大学的软件工程的一名学生,学校开设了一些关于系统开发的课程,纸上得来终觉浅,学校的课程课时较短,想要在56个课时之内学会一些公司需要的技能,无疑是纸上谈兵,一门语言的学习,需要的 ...
- pgm11
这里简要的讨论 hybrid network 与一些时序数据的分析. hybrid network 指网络中存在离散随机变量与连续随机变量,这种情况下一般非常麻烦,这主要是因为连续型随机变量需要使用某 ...
- ceph PG数量调整/PG的状态说明
优化: PG Number PG和PGP数量一定要根据OSD的数量进行调整,计算公式如下,但是最后算出的结果一定要接近或者等于一个2的指数.调整PGP不会引起PG内的对象的分裂,但是会引起PG的分布的 ...
- 【Linux】MGR部署脚本
脚本没有完善,现在只有上半部分的基础环境搭建 [准备条件] 1.三个节点的防火墙关闭 2.原有mysql卸载删除 3.文件夹名字: mgr 所有的源码包都放在mgr的文件夹下 4.文件位置: /roo ...
- Python从入门到放弃系列(Django/Flask/爬虫)
第一篇 Django从入门到放弃 第二篇 Flask 第二篇 爬虫
- Java11实战:模块化的 Netty RPC 服务项目
Java11实战:模块化的 Netty RPC 服务项目 作者:枫叶lhz链接:https://www.jianshu.com/p/19b81178d8c1來源:简书简书著作权归作者所有,任何形式的转 ...
- 自学Zabbix3.12.5-动作Action-Condition配置
点击返回:自学Zabbix之路 点击返回:自学Zabbix4.0之路 点击返回:自学zabbix集锦 3.12.5 自学Zabbix3.12.5-动作Action-Condition配置 报警,肯定是 ...