JavaScript中的深拷贝和浅拷贝问题

Javascript 中的深拷贝和浅拷贝

深拷贝、浅拷贝是什么意思?

  • 浅拷贝:

    拷贝的是引用,修改拷贝后的数据会影响原数据, 使得原数据不安全

  • 深拷贝:

    拷贝的时候生成新数据,修改拷贝以后不会影响原数据

浅拷贝例子

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
/**
* 拷贝数据方法:
* 1. 直接赋值给一个变量 // 浅拷贝
* 2. Object.assign() // 浅拷贝
* 3. Array.prototype.concat() // 浅拷贝
* 4. Array.prototype.slice() // 浅拷贝
* 5. JSON.parse(JSON.stringify()) // 深拷贝(深度克隆), 拷贝的数据里不能有函数, 处理不了
*/

let obj = {
username: 'kobe'
};
let obj2 = Object.assign(obj);
console.log(obj2);
obj.username = 'wade';
console.log(obj2);

let arr = [1, 3, { username: 'kobe' }];
let arr2 = arr.concat();
console.log(arr2);
arr2[2].username = 'wade';
console.log(arr);

let arr3 = arr.slice();
arr3[2].username = 'Iverson';
arr3[1] = 2;
console.log(arr);

let arr4 = JSON.parse(JSON.stringify(arr));
arr4[2].username = 'duncan';
console.log(arr);

如何实现深拷贝(主要针对 对象/数组, 基本数据类型不存在深拷贝和浅拷贝的概念)

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
/**
* 知识点储备
* 如何判断数据类型:
* 1. typeof 返回的数据类型: String, Number, Boolean, Undefined, Object, Function
* 2. 利用 Object.prototype,toString.call(obj) 方法
*/

// 定义检测数据类型的功能函数
function checkedType(target) {
return Object.prototype.toString.call(target).slice(8, -1);
}

// 实现深拷贝(深度克隆)
function deepClone(target) {
// 判断拷贝的数据类型
// 初始化变量result 成为最终拷贝的数据
let result;
let targetType = checkedType(target);
if (targetType === 'Object') {
result = {};
} else if (targetType === 'Array') {
result = [];
} else {
return target;
}

// 遍历目标数据
for (let i in target) {
let value = target[i];
// 判断目标结构里的每一项值是否存在对象或数组
if (checkedType(value) === 'Object' || checkedType(value) === 'Array') {
// 通过递归继续遍历获取到的value值
result[i] = deepClone(value);
} else {
result[i] = value;
}
}

return result;
}

let arr = [1, 2, { username: 'kobe', age: 41 }, 'abc'];
let arr1 = deepClone(arr);
arr1[2].username = 'wade';
console.log(arr);
console.log(arr1);
// [ 1, 2, { username: 'kobe', age: 41 }, 'abc' ] arr
// [ 1, 2, { username: 'wade', age: 41 }, 'abc' ] arr1