🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
js中的两种变量类型,即值类型(数值、布尔值、null、undefined)和引用类型(对象、数组、函数)。 值类型保存于栈中,而引用类型保存在堆中,值类型和引用类型赋值时的不同,值类型赋值时会在内存中开辟一块新的空间,然后把赋过来的值保存于这块新开辟的空间中,引用类型赋值时也会开辟一块新的空间,不同的时新的空间保存的是赋值对象虽在的地址(即浅拷贝,也就是说赋值和被赋值对象引用的是同一个对象,所以改变其中任何一个对象时,另一个会随之改变)。所以深拷贝和浅拷贝概念只针对于引用类型,对于值类型来说没有意义。 编写程序时,往往需要被赋值的对象生成一个新的对象,而不是赋值对象的一个引用,这个时候我们就需要使用深拷贝。 ~~~ function test() { 'use strict'; // 浅拷贝 let obj1 = { a: 0 , b: { c: 0}}; let obj2 = Object.assign({}, obj1); console.log(JSON.stringify(obj2)); // { a: 0, b: { c: 0}} obj1.a = 1; console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 0}} console.log(JSON.stringify(obj2)); // { a: 0, b: { c: 0}} obj2.a = 2; console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 0}} console.log(JSON.stringify(obj2)); // { a: 2, b: { c: 0}} obj2.b.c = 3; console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 3}} console.log(JSON.stringify(obj2)); // { a: 2, b: { c: 3}} // 深拷贝 obj1 = { a: 0 , b: { c: 0}}; let obj3 = JSON.parse(JSON.stringify(obj1)); obj1.a = 4; obj1.b.c = 4; console.log(JSON.stringify(obj3)); // { a: 0, b: { c: 0}} } ~~~ ### 1.万能的for循环实现对象的深拷贝 在很多时候,for循环能够解决大问题。 ~~~ var obj = { name: 'FungLeo', sex: 'man', old: '18' } var obj2 = copyObj(obj) function copyObj(obj) { let res = {} for (var key in obj) { res[key] = obj[key] } return res } ~~~ ### 2.转换成json再转换成对象实现对象的深拷贝 上面的代码实在是比较长,所以,用一个更暴力的方法吧!代码如下: ~~~ var obj = { name: 'FungLeo', sex: 'man', old: '18' } var obj2 = JSON.parse(JSON.stringify(obj)) ~~~ ![](https://box.kancloud.cn/65a0a6ad1b1d534e4d2e6196392a4cec_604x171.png) ### 3.扩展运算符实现对象的深拷贝 ~~~ var obj = { name: 'FungLeo', sex: 'man', old: '18' } var { ...obj2 } = obj obj.old = '22' console.log(obj) console.log(obj2) ~~~ ![](https://box.kancloud.cn/049e475f485c89d8c2f388609ac2ed65_422x229.png)