浅拷贝

  • 主要针对对象的属性对应的值也是复杂类型的情况,此时浅拷贝的对象在对属性值为复杂类型的属性进行修改时,也会影响到原始对象,即被拷贝的对象。

对象的浅拷贝

  • Object.assign()
  • 展开运算符
  • for…in… + Object.hasOwnProperty()
  • Object.keys()

数组的浅拷贝

  • Array.slice(start, end) — 左闭右开
  • Array.concat() —使用空数组拼接

深拷贝

  • JSON.parse(JSON.stringify())
    • 无法拷贝函数、特殊对象:Date、Regex
    • 不会拷贝原型链上的属性
    • 会忽略Symbol和undefined属性值对应的属性

手写深拷贝函数

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
function deepClone(source: Object, cloneMap = new Map()) {
if (!(source instanceof Object) || source === null) {
return source;
}
if (cloneMap.has(source)) {
return cloneMap.get(source);
}
const target = Array.isArray(source)
? []
: source instanceof Date
? new Date(source)
: source instanceof RegExp
? new RegExp(source.source, source.flags)
: {};
cloneMap.set(source, target);
for (const key in source) {
if (typeof source[key] === "object" && source[key] !== null) {
target[key] = deepClone(source[key], cloneMap);
} else {
target[key] = source[key];
}
}
const symbols = Object.getOwnPropertySymbols(source);
for(const symKey of symbols) {
target[symKey] = deepClone(source[symKey], cloneMap);
}
return target;
}