05-深浅拷贝方式/JSON.parse(JSON.stringify)深拷贝的缺陷

  • for...in循环:只遍历对象自身的和继承的可枚举的属性
  • Object.keys():返回对象自身的所有可枚举的属性的键名
  • JSON.stringify():只串行化对象自身的可枚举的属性
  • Object.assign() :只拷贝对象自身的可枚举的属性。

1.浅拷贝:
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 
 4 <head>
 5     <meta charset="UTF-8">
 6     <title>Document</title>
 7 </head>
 8 
 9 <body>
10     <script>
11         // 浅拷贝只是拷贝一层, 更深层次对象级别的只拷贝引用.
12         // 深拷贝拷贝多层, 每一级别的数据都会拷贝.
13         var obj = {
14             id: 1,
15             name: 'andy',
16             msg: {
17                 age: 18
18             }
19         };
20         var o = {};
21         // for (var k in obj) {
22         //     // k 是属性名   obj[k] 属性值
23         //     o[k] = obj[k];
24         // }
25         // console.log(o);
26         // o.msg.age = 20;
27         // console.log(obj);
28 
29         console.log('--------------');
30         Object.assign(o, obj);
31         console.log(o);
32         o.msg.age = 20;
33         console.log(obj);
34     </script>
35 </body>
36 
37 </html>

2.深拷贝

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 
 4 <head>
 5     <meta charset="UTF-8">
 6     <title>Document</title>
 7 </head>
 8 
 9 <body>
10     <script>
11         // 深拷贝拷贝多层, 每一级别的数据都会拷贝.
12         var obj = {
13             id: 1,
14             name: 'andy',
15             msg: {
16                 age: 18
17             },
18             color: ['pink', 'red']
19         };
20         var o = {};
21         // 封装函数 
22         function deepCopy(newobj, oldobj) {
23             for (var k in oldobj) {
24                 // 判断我们的属性值属于那种数据类型
25                 // 1. 获取属性值  oldobj[k]
26                 var item = oldobj[k];
27                 // 2. 判断这个值是否是数组
28                 if (item instanceof Array) {
29                     newobj[k] = [];
30                     deepCopy(newobj[k], item)
31                 } else if (item instanceof Object) {
32                     // 3. 判断这个值是否是对象
33                     newobj[k] = {};
34                     deepCopy(newobj[k], item)
35                 } else {
36                     // 4. 属于简单数据类型
37                     newobj[k] = item;
38                 }
39 
40             }
41         }
42         deepCopy(o, obj);
43         console.log(o);
44 
45         var arr = [];
46         console.log(arr instanceof Object);
47         o.msg.age = 20;
48         console.log(obj);
49     </script>
50 </body>
51 
52 </html>

深拷贝另一种:

var objCopy = JSON.parse(JSON.stringify(obj))

JSON.parse(JSON.stringify(obj))我们一般用来深拷贝,其过程说白了 就是利用JSON.stringify 将js对象序列化(JSON字符串),再使用JSON.parse来反序列化(还原)js对象;序列化的作用是存储(对象本身存储的只是一个地址映射,如果断电,对象将不复存在,因此需将对象的内容转换成字符串的形式再保存在磁盘上 )和传输(例如 如果请求的Content-Type是 application/x-www-form-urlencoded,则前端这边需要使用qs.stringify(data)来序列化参数再传给后端,否则后端接受不到; ps: Content-Type 为 application/json;charset=UTF-8或者 multipart/form-data 则可以不需要 )。


浅拷贝:只能拷贝一层,对于多层里面有复杂数据类型的,只拷贝的内存空间的指向,
和原来的被拷贝对象指向同一内存空间

深拷贝:完全拷贝,有自己的独立内存空间,不会对被拷贝对象造成干扰,两者互相独立。

用JSON.parse(JSON.stringify())实现深拷贝的弊端
JSON.parse(JSON.stringify())深拷贝的弊端:
1.如果obj里面有时间对象,则JSON.stringify后再JSON.parse的结果,
时间将只是字符串的形式。而不是时间对象;

2.如果obj里有RegExpError对象,则序列化的结果将只得到空对象;
3.如果obj里有函数,undefined,则序列化的结果会把函数或 undefined丢失;
4.如果obj里有NaN、Infinity和-Infinity,则序列化的结果会变成null
5.JSON.stringify()只能序列化对象的可枚举的自有属性,例如 如果obj中的对象是有构造函数生成的,
则使用JSON.parse(JSON.stringify(obj))深拷贝后,会丢弃对象的constructor

6.如果对象中存在循环引用的情况也无法正确实现深拷贝;



原文地址:https://www.cnblogs.com/haoqiyouyu/p/14555626.html