Js克隆对象
Js克隆对象
1 浅复制
具体方法
// 数组
Array.prototype.slice
const oldArr = new Array(100).fill(null).map(() => Math.random() * 100 | 0)
const newArr = oldArr.slice()
// 普通对象
Object.assign
const oldObj = new Object() // plain object
const newObj = Object.assign({}, oldObj)
2 深复制
1) 转字符串再还原
function deepClone(obj) {
return JSON.parse(JSON.stringify(obj))
}
2) 便利对象,递归克隆
function deepClone(obj) {
if ( typeof obj !== 'object' ) {
return obj
}
const ret = Array.isArray(obj) ? [] : {}
for ( let i in obj ) {
ret[i] = deepClone(obj[i])
}
return ret
}
3)循环引用对象
如果采用以上两种克隆方式,遇到循环引用对象会导致报错
function updateClone(obj) {
const map = new Map();
function deepClone(obj) {
if (typeof obj !== 'object') {
return obj;
}
const ret = Array.isArray(obj) ? [] : {};
for (let i in obj) {
const dist = obj[i];
if (map.has(dist)) {
continue;
} else {
map.set(dist, true);
ret[i] = dist;
}
}
return ret;
}
return deepClone(obj);
}
4)难克隆对象,甚至无法克隆对象
比如Date, Function, Error或者自定义的一些class构造对象
const oldDate = new Date()
const newDate = new Date(+oldDate)
// Date可以处理
// Function 使用toString,但是考虑到可能bind有些context,而且函数的作用域链,这些没法搞
// Error stack message这些也没法处理
// Window构造对象这些更是无法处理
5)对象属性key异常情况
属性不可枚举
Object.getOwnPropertyDescriptors({a:1})

这个可以通过使用Object.getOwnPropertyNames获取,但是赋值的时候得注意一下,也应该是enumerable: false
遍历了原型链上属性,方法
某些同学写代码不注意,直接Object.prototype.xx = xx
那么这个数据就是可以枚举的,for in慢的原因也是因为他不止遍历当前对象,他会沿着原型链一直向上找
可以通过hasOwnProperty过滤掉
总结
其实大部分时候只需要能够克隆plain object就行了,太过于复杂的情况无需考虑
Js克隆对象的更多相关文章
- js深度克隆对象
js深度克隆对象 js深度克隆对象简单的记录一下,如下代码: var obj = { typeOf: function(obj) { const toString = Object.prototype ...
- 原生JS的对象常用操作总结
前端时间写了篇怎么判断js对象相等的文章,一直在期待大神给点消息,无奈一直杳无音讯,还是自己写个函数来进行判断,下面总结一些常用的对象操作的方法. 咋们来个先抑后扬的方式,先放出几个基本的 ...
- 【PHP面向对象(OOP)编程入门教程】17.克隆对象__clone()方法
有的时候我们需要在一个项目里面,使用两个或多个一样的对象,如果你使用“new”关键字重新创建对象的话,再赋值上相同的属性,这样做比较烦琐而且也容易出错,所以要根据一个对象完全克隆出一个一模一样的对象, ...
- js定义对象的几种容易犯的错误
//js定义对象的几种容易犯的错误function Person() { getName = function (){ console.info(1); }; return this;}//Perso ...
- 模仿console自写函数打印js的对象
本以为写个递归函数就可以将js的对象打印出来. 当然第一个想到的估计是JSON.stringify() 这个函数.但这个函数打印到浏览器 显示效果不友好.最友好的显示肯定是 控制台打印咯. 结果尝试打 ...
- js自定义对象
一,概述 在Java语言中,我们可以定义自己的类,并根据这些类创建对象来使用,在Javascript中,我们也可以定义自己的类,例如定义User类.Hashtable类等等. 目前在Javascrip ...
- Atitit 跨平台异常处理(2)--------异常转换 -----java c# js异常对象结构比较and转换
Atitit 跨平台异常处理(2)--------异常转换 -----java c# js异常对象结构比较and转换 { "@type":"java.lang.Runti ...
- js中对象使用
简单记录javascript中对象的使用 一.创建对象 //创建一个空对象 var o={}; //创建一个含有两个属性的对象,x.y var o2={x:12,y:'12',name:'JS'}; ...
- JavaScript学习06 JS事件对象
JavaScript学习06 JS事件对象 事件对象:当事件发生时,浏览器自动建立该对象,并包含该事件的类型.鼠标坐标等. 事件对象的属性:格式:event.属性. 一些说明: event代表事件的状 ...
- [转]JS中对象与字符串的互相转换
原文地址:http://www.cnblogs.com/luminji/p/3617160.html 在使用 JSON2.JS 文件的 JSON.parse(data) 方法时候,碰到了问题: thr ...
随机推荐
- 鸿蒙版《智慧农业APP》通过华为云IoT平台实现软件硬件互联
一.原理图 本篇不涉及硬件相关的功能开发,硬件设备使用MQTT客户端模拟,如果有硬件相关经验的可以直接使用真实硬件代替MQTT客户端. 1.华为云物联网服务器 华为云物联网平台是硬件设备端跟移动APP ...
- odoo知识图谱
最近项目交付后,准备将系统整个知识点整理一下,下面是目录,后面针对目录编写文档--todo
- 浅谈RMI、JRMP、JNDI
目录 RMI 概念: 为什么要有RMI? RMI的构成: 如何使用RMI 注意!!! JRMP(是RMI的通信协议的名字) 概念 查看通信过程 工具使用 攻击Server 攻击Client JNDI ...
- 「Log」2023.8.15 小记
序幕 七点多到校,整理博客,开始调昨天没整完的题. 手算哈希,把所有部分都先改成暴力. 好消息,暴力没问题,准备改成正解. 学长开始讲课,AC 自动机,秒了. 接着调题,过了.开心. \(\color ...
- Java安全_SQL注入
[!NOTE] 本次学习使用开源项目: https://github.com/JoyChou93/java-sec-code/blob/master/src/main/java/org/joychou ...
- 【中英】【吴恩达课后测验】Course 2 - 改善深层神经网络 - 第三周测验
[中英][吴恩达课后测验]Course 2 - 改善深层神经网络 - 第三周测验 上一篇:[课程2 - 第二周编程作业]※※※※※ [回到目录]※※※※※下一篇:[课程2 - 第三周编程作业] 第3周 ...
- shell 使用awk 分析nginx日志取出400 的请求写入文件,然后php读取文件处理数据
使用awk分析昨日 的nginx日志,将服务端未处理成功的400 请求,重新请求,将数据补进去 下面是代码,如果有类似问题的话,可以参考一下 #!/bin/bash ## 1. shell 获取日期获 ...
- 灵活、可用、高扩展,EasyMR 带来全新 Yarn 的队列管理功能及可视化配置
YARN(Yet Another Resource Negotiator)是 Hadoop 生态系统中的资源调度器,主要用于资源管理和作业调度.YARN 自身具备队列管理功能,通过对 YARN 资源队 ...
- Linux搭建Docker环境
安装Docker CE 安装Docker的依赖库. yum install -y yum-utils device-mapper-persistent-data lvm2 添加Docker CE的软件 ...
- springBoot启动 Error running Application. Command line is too long. Shorten the command line via JAR manifest or via a classpath file and rerun.
1. 打开SpringBoot启动配置 2.选择shorten command line 3.apply保存就行了