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里有RegExp
、Error
对象,则序列化的结果将只得到空对象;
3.如果obj里有函数,undefined
,则序列化的结果会把函数或 undefined丢失;
4.如果obj里有NaN、Infinity和-Infinity,则序列化的结果会变成null
5.JSON.stringify()
只能序列化对象的可枚举的自有属性,例如 如果obj中的对象是有构造函数生成的,
则使用JSON.parse(JSON.stringify(obj))
深拷贝后,会丢弃对象的constructor
;
6.如果对象中存在循环引用的情况也无法正确实现深拷贝;