1、总结
浅拷贝和深拷贝都是用于对象拷贝的,区别在于浅拷贝是复制对象地址的,只要数据改变,原对象数据会跟着改变;而深拷贝是复制数据,再新建一个地址,数据改变不会影响原对象的数据,深拷贝有两种方法,一种是JSON转换,另一种是用递归方法复制对象数据,推荐用JSON转换,方便快捷,就是这么简单。
2、浅拷贝
- 拷贝的是地址,修改拷贝后的数据对原对象有影响
<script> /* 1、浅拷贝:拷贝的是地址,修改拷贝后的数据对原对象有影响 2、深拷贝:拷贝的是数据,修改拷贝后的数据对原对象没有影响 */ var obj = { name: 'jasmine', age: 18, hobby: ['画画', '唱歌'], friend: { name: 'qiqi', age: 18 } } // 3、浅拷贝 var obj1 = obj; obj.name = 'jasmine1'; console.log(obj); // jasmine1 console.log(obj1); // jasmine1 </script>
3、深拷贝
- 拷贝的是数据,重新创建一个地址,修改拷贝后的数据对原对象没有影响
4、深拷贝有两种方法(JSON和递归)
JSON:
- let json = JSON.stringify(obj);
- obj1 = JSON.parse(json);
// 4、深拷贝,有两种拷贝方法 // 4.1、第一种方法:用json转换 // 4.2、第二种方法:递归 var obj = { name: 'jasmine', age: 18, hobby: ['画画', '唱歌'], friend: { name: 'qiqi', age: 18 } } // 把对象转为JSON格式的字符串,自动进行深拷贝 let json = JSON.stringify(obj); console.log(json); // 再把JSON格式的字符串转为对象 obj1 = JSON.parse(json); obj1.name = "jasmine"; console.log(obj1); // jasmine
递归:
- 用for循环遍历数据,把数据添加到新的对象中,如果里面有引用类型数据,则要用到递归。
- 不能直接拷贝地址,要声明一个空数组然后遍历对象数组,把里面的元素添加到新的数组里面
- 对象也是一样的,创建一个新的对象,然后把对象的数据放到里面即可
- 相对于递归,用JSON格式转换会方便很多
// 4.2、第二种方法:递归,把所有的属性添加到新的对象中 // 如果里面有引用类型数据(数组、对象), // 则不能直接拷贝地址,要声明一个空数组然后遍历对象数组,把里面的元素添加到新的数组里面 // 对象也是一样的,创建一个新的对象,然后把对象的数据放到里面即可 // 相对于递归,用JSON格式转换会方便很多 function copy(newObj, obj) { for (let i in obj) { // 判断是不是数组类型 if (obj[i] instanceof Array) { // 声明一个空数组,然后拷贝数组里面的数组 newObj[i] = []; copy(newObj[i], obj[i]); // 判断是不是数组类型 } else if (obj[i] instanceof Object) { // 声明一个空数组,然后拷贝对象里面的数组 newObj[i] = {}; copy(newObj[i], obj[i]); } else { newObj[i] = obj[i]; } } } obj1 = {}; copy(obj1, obj); obj1.hobby[0] = '插画'; console.log(obj1);
5、源代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> </body> <script> /* 1、浅拷贝:拷贝的是地址,修改拷贝后的数据对原对象有影响 2、深拷贝:拷贝的是数据,修改拷贝后的数据对原对象没有影响 */ var obj = { name: 'jasmine', age: 18, hobby: ['画画', '唱歌'], friend: { name: 'qiqi', age: 18 } } // 3、浅拷贝 var obj1 = obj; obj.name = 'jasmine1'; console.log('原对象:') console.log(obj); // jasmine1 console.log('浅拷贝:') console.log(obj1); // jasmine1 // 4、深拷贝,有两种拷贝方法 // 4.1、第一种方法:用json转换 // 把对象转为JSON格式的字符串,自动进行深拷贝 let json = JSON.stringify(obj); console.log('转为JSON字符串:') console.log(json); // 再把JSON格式的字符串转为对象 obj1 = JSON.parse(json); obj1.name = "jasmine"; console.log('深拷贝(JSON):') console.log(obj1); // jasmine // 4.2、第二种方法:递归,把所有的属性添加到新的对象中 // 如果里面有引用类型数据(数组、对象), // 则不能直接拷贝地址,要声明一个空数组然后遍历对象数组,把里面的元素添加到新的数组里面 // 对象也是一样的,创建一个新的对象,然后把对象的数据放到里面即可 // 相对于递归,用JSON格式转换会方便很多 function copy(newObj, obj) { for (let i in obj) { // 判断是不是数组类型 if (obj[i] instanceof Array) { // 声明一个空数组,然后拷贝数组里面的数组 newObj[i] = []; copy(newObj[i], obj[i]); // 判断是不是数组类型 } else if (obj[i] instanceof Object) { // 声明一个空数组,然后拷贝对象里面的数组 newObj[i] = {}; copy(newObj[i], obj[i]); } else { newObj[i] = obj[i]; } } } obj1 = {}; copy(obj1, obj); obj1.hobby[0] = '插画'; console.log(obj1); </script> </html>