利用JSON.parse(JSON.stringify(obj))完成对象深拷贝

我们知道lodash、immutable.js等工具库都封装了一些深拷贝方法,不过有时候为了方便我们还是会直接使用JSON.parse(JSON.stringify(obj))来进行对象的拷贝。

使用

1
newObj = JSON.parse(JSON.stringify(originObj));

作用范围

数组Array、json对象

例子

数组:

1
2
3
4
5
6
7
8
9
10
let originArr = [1, 2, 3, 4];
let newArr1 = originArr;
let newArr2 = JSON.parse(JSON.stringify(originArr));

console.log(newArr1 === originArr); // true
console.log(newArr2 === originArr); // false

originArr[0] = 'change';
console.log(newArr1[0]); // 'change'
console.log(newArr2[0]); // 1

json对象:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
let originObj = {
a: 'a',
b: 'b',
c: {
c1: 'c1',
c2: 'c2'
}
};
let newObj1 = originObj;
let newObj2 = JSON.parse(JSON.stringify(originObj));

console.log(newObj1 === originObj); // true
console.log(newObj2 === originObj); // false

originObj.a = 'a_change';
console.log(newObj1.a); // 'a_change'
console.log(newObj2.a); // 'a'

originObj.c.c1 = 'c1_change';
console.log(newObj1.c.c1); // 'c1_change'
console.log(newObj2.c.c1); // 'c1'

注意

undefined、function、symbol会被忽略(如果一个对象有toJSON属性,当它被序列化的时候,不会对该对象进行序列化,而是将它的toJSON方法的返回值进行序列化。)

例子

1
2
3
4
5
6
7
8
9
10
let originObj = {
a: undefined,
b: 'b',
c: function () { console.log('function c'); }
};
originObj[Symbol()] = 'simbol';
let newObj1 = JSON.parse(JSON.stringify(originObj));

console.log(originObj); // {a: undefined, b: "b", c: ƒ, Symbol(): "simbol"}
console.log(newObj1); // {b: "b"}

* JSON.stringify方法定义

1
JSON.stringify ( value [, replacer] [ , space] )

params:

  • value:必选,要转换的值(包括所有的数据类型,通常是对象或者数组)
  • replace:可选,用于要转换结果的函数或者数组;如果replace是数组,仅仅是转换具有该键值的成员,成员的转换顺序和键在数组中的顺序一致;如果replace是函数,会传入每一个成员的键和值,使用的是返回值而不是原始值,如果函数返回的是undefined,则排除该成员。
  • space:可选,向返回值JSON文本添加缩进、空格和换行符以使其更易于读取。