JS 对象如何实现深拷贝

发布狂
• 阅读 3220

如何实现一个对象的深拷贝?

方法1:使用JSON (对象的序列化和反序列化)

需要注意的是:在引用数据类型中,地址是保存在栈区的,属性值存放在堆区的,不同的地址指向的值是不一样的,这里是深拷贝的写法,变量地址是互不影响的,所以是obj == obj1为false,而在浅拷贝中就是为true的,因为在赋值的同时obj会把地址一起赋值给obj1,使他们的地址指向堆区的同一个值


// 如何实现一个对象的深拷贝?

//第一种方法
// 对象序列化

//创建一个对象
var obj = {
    name:'zhangsan',
    age:13
}
//因为是深拷贝 
//将obj序列化和反序列化后  赋值给一个obj1   
var obj1 = JSON.parse(JSON.stringify(obj));
console.log(JSON.stringify(obj), typeof JSON.stringify(obj));  //string
console.log(obj1,typeof obj1);   // { name: 'zhangsan', age: 13 }    object
console.log(obj == obj1);   //false   //因为反序列后obj1引用地址发生了改变
console.log(obj === obj1);  //false

//改变obj1中的name属性
obj1.name = 'lisi';
//打印输出的obj的name属性没有改变   
//验证深拷贝只作用于栈区,栈区中变量和变量之间是独立存在的,值得变换不会互相影响
console.log(obj,obj1);   // { name: 'zhangsan', age: 13 } { name: 'lisi', age: 13 }

方法2:第三方库lodash 的cloneDeep

Lodash 是一个一致性、模块化、高性能的 JavaScript 实用工具库。

要用lodash标签库 要先导入lodash
在当前目录下 终端中 执行指令 npm i --save lodash


//第二种方法
// 第三方库lodash的cloneDeep
//lodash常用_来定义
var _ = require('lodash');
//创建一个对象
var obj = {
    name:'zhangsan',
    age:18
}
//使用cloneDeep方法   cloneDeep相当于clone,就是递归拷贝(这个我不是很明白,但是是这么用的)
var obj2 = _.cloneDeep(obj);
//同样是改变obj2的name属性
obj2.age = 20;
//打印输出obj和obj2   发现只有obj2的name属性值改变了  原理和方法一样
console.log(obj);  //{ name: 'zhangsan', age: 18 }

console.log(obj2);  //{ name: 'zhangsan', age: 20 }

方法3:Object.assign()实现深拷贝

// Object.assign(obj1,obj2); 两个参数实现对象复制、拷贝 第一个参数是目标对象
let obj1 = {}
let obj2 = {
    name:'xxx',
    age:22
}
//两个参数实现对象复制,拷贝   第一个参数obj1是目标对象
//把obj2中的内容复制到obj1对象当中并返回obj1对象
let res1 = Object.assign(obj1,obj2);
console.log(res1);//{ name: 'xxx', age: 22 }
console.log(obj1);//{ name: 'xxx', age: 22 }
obj1.name = '小仙女'
console.log(obj2);//{ name: 'xxx', age: 22 } //name没有改变,证明是深拷贝
obj2.name = '开心超人'
console.log(obj1);  //{ name: '小仙女', age: 22 }  //没有改变
//深拷贝,指向的堆区中的值不相同
console.log(obj1 === obj2); //false

方法4:使用拓展运算符... 实现深拷贝

// 使用拓展运算符... 实现深拷贝
let obj1 = {
    name: 'tom',
    age: 13
}
//用到右侧是展开
let obj2 = {
    //把obj1对象拆成键值对
    ...obj1,
    //新增属性
    gender: 'male'
}

console.log(obj2); //{ name: 'tom', age: 13 , gender: 'male' }
obj1.name = '玛卡巴卡'
console.log(obj2);//{ name: 'tom', age: 13, gender: 'male' }  //没有改变  验证是深拷贝
console.log(obj1 === obj2); //false

还知道一个利用递归,增强版for,还有jquery中的继承方法实现深拷贝,但是呢,我不会。。。。

很多种方法,待更新、、、、、、、、

分享一个偶然间看到的大佬的关于深拷贝与浅拷贝的讲解博客,总结的太好懂了,厉害厉害

https://segmentfault.com/a/11...

JS 对象如何实现深拷贝

JS 对象如何实现深拷贝

点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Wesley13 Wesley13
4年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Wesley13 Wesley13
4年前
java 复制Map对象(深拷贝与浅拷贝)
java复制Map对象(深拷贝与浅拷贝)CreationTime2018年6月4日10点00分Author:Marydon1.深拷贝与浅拷贝  浅拷贝:只复制对象的引用,两个引用仍然指向同一个对象
仔细看看,会有收获。js深浅拷贝
好好理解深浅拷贝和赋值(针对引用类型)赋值:两个对象指向同一内存地址。结果,无论是修改基本类型还是引用类型,两个对象的值都会改变。浅拷贝:两个对象指向不同的内存地址,但是他们中的引用类型数据指向同一内存地址。结果,修改引用类型,两个对象的值都会改变;修改基本类型,互不影响。深拷贝:两个对象指向不同的内存地址,他们中的引用类型也指向不同的内存地址。结果,均互不
Java对象拷贝原理剖析及最佳实践
作者:宁海翔1前言对象拷贝,是我们在开发过程中,绕不开的过程,既存在于Po、Dto、Do、Vo各个表现层数据的转换,也存在于系统交互如序列化、反序列化。Java对象拷贝分为深拷贝和浅拷贝,目前常用的属性拷贝工具,包括Apache的
菜园前端 菜园前端
2年前
带你了解JS对象的浅拷贝和深拷贝
以下主要介绍了正常情况下的拷贝、浅拷贝、深拷贝三种方式的区别。正常拷贝:复制一个对象,它们的内存地址是相同的浅拷贝:拷贝对象的第一层属性深拷贝:拷贝对象多层的属性正常拷贝假设我们要复制一个对象,如果不对其进行深拷贝,那么改变其中一个对象后,另外一个对象也会
Souleigh ✨ Souleigh ✨
5年前
实现深拷贝的多种方式
实现深拷贝的多种方式简单来说,深拷贝主要是将另一个对象的属性值拷贝过来之后,另一个对象的属性值并不受到影响,因为此时它自己在堆中开辟了自己的内存区域,不受外界干扰。浅拷贝主要拷贝的是对象的引用值,当改变对象的值,另一个对象的值也会发生变化。1.简单深拷贝(一层浅拷贝)①for循环拷贝//只复制第一层的浅拷贝javascriptfunc
Wesley13 Wesley13
4年前
Java深拷贝和浅拷贝
1.浅复制与深复制概念⑴浅拷贝(浅克隆)   复制出来的对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。⑵深拷贝(深克隆)   复制出来的所有变量都含有与原来的对象相同的值,那些引用其他对象的变量将指向复制出来的新对象,而不再是原有的那些被引用的对象。换言之,深复制
Wesley13 Wesley13
4年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
4年前
unity将 -u4E00 这种 编码 转汉字 方法
 unity中直接使用 JsonMapper.ToJson(对象),取到的字符串,里面汉字可能是\\u4E00类似这种其实也不用转,服务器会通过类似fastjson发序列化的方式,将json转对象,获取对象的值就是中文但是有时服务器要求将传参中字符串中类似\\u4E00这种转汉字,就需要下面 publ
发布狂
发布狂
Lv1
江汉思归客,乾坤一腐儒
文章
4
粉丝
0
获赞
0