1. 如果obj里面有时间对象,则JSON.stringify后再JSON.parse的结果,时间将只是字符串的形式;而不是时间对象。

1
2
3
4
5
6
var test = {
name:'a',
date:[new Date(153662760000), new Date(15400476000000)],
}
let b;
b = JSON.parse(JSON.stringify(test));

test和b的结果

测试b和test类型

2. 如果obj里有RegExp 、Error对象,则序列化的结果只得到空对象。

3. 如果obj里有函数, undefined ,则序列化的结果会把函数或undefined丢失。

1
2
3
4
5
6
7
8
9
const test = {
name:'a',
date:function hehe(){
console.log('肖战')
},
};
const copyed = JSON.parse(JSON.stringify(test));
test.name = '魏无羡';
console.error('debugger',test,copyed);

函数

undefined

4. 如果obj里有NaN、infinity和-Infinity,则序列化的结果会变为null

5. JSON.stringify()只能序列化对象的可枚举的自有属性,例如:如果obj中的对象是由构造函数生成的,则使用JSON.parse(JSON.stringify(obj))深拷贝后,会丢弃对象constructor;

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

如果拷贝的对象不涉及上面的情况,可以使用JSON.parse(JSON.stringify(obj))实现深拷贝,但是涉及上面的情况,可以考虑使用下面的方式实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// 实现深拷贝函数
function deepClone(data) {
const type = this.judgeType(data);
let obj = null;
if(type === 'array'){
obj = [];
for (let i = 0; i < data.length; i++) {
obj.push(this.deepClone(data[i]));
}
}else if( type === 'object'){
obj ={};
for (let key in data) {
if (data.hasOwnProperty(key)) {
obj[key] = this.deepClone(data[key])
}
}
}else{
return data;
}
return obj;
}

function judgeType(obj) {
const toString = Object.prototype.toString;
const map ={
'[object Boolean]': 'boolean',
'[object Number]': 'number',
'[object String]': 'string',
'[object Function]': 'function',
'[object Array]': 'array',
'[object Date]': 'date',
'[object RegExp]': 'regExp',
'[object Undefined]': 'undefined',
'[object Null]': 'null',
'[object Object]': 'object',
}
if(obj instanceof Element){
return 'element';
}
return map[toString.call(obj)];
}
const test ={
name:'a',
date:[1,2,3]
}
console.log(deepClone(test));
test.date[0] = 4;
console.log(test);