头图

JS 对象如何实现深拷贝

夏茗星

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

方法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...

阅读 2.4k

当野心追赶不上才华,便静下心来努力

30 声望
7 粉丝
0 条评论

当野心追赶不上才华,便静下心来努力

30 声望
7 粉丝
宣传栏