0%

深拷贝

深度克隆 (深拷贝)

拷贝数据的方法

1 —— 直接赋值 =
2 —— Object.assign()
3 —— Array.prototype.concat()
4 —— Array.prototype.slice()
5 —— JSON.parse(JSON.stringify()), 拷贝的数据里 不能有函数

  • 因为 JSON.stringify / JSON.parse 没法处理函数

以上只有 5 是深拷贝

1
2
3
4
var arr = [1, 2, { name: 'zs' }]
var arr2 = JSON.parse(JSON.stringify(arr))
arr2[2].name = 'ls'
console.log(arr) // [1, 2, { name: 'zs' }]
  • 拷贝后 (针对对象/数组) 修改新变量会改变源变量的方式称为 浅拷贝

    • 浅拷贝特点
      • 拷贝后生成的新数据的修改会影响原数据, 使得原数据不安全
  • 拷贝后 (针对对象/数组) 修改新变量不会改变源变量的方式称为 深拷贝

如何实现深拷贝?

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
// 检测数据类型 返回 Array、Object、String...
// Object.prototype.toString.call() 方法返回的是 '[object Object/Array/String/Number]'
// Object.prototype.toString.call('33') => '[object String]'
// Object.prototype.toString.call(22) => '[object Number]'
// Object.prototype.toString.call([]) => '[object Array]'
// Object.prototype.toString.call({}) => '[object Object]'
function checkType(target) {
return Object.prototype.toString.call(target).slice(8, -1)
}

// 深拷贝函数
function clone(target) {
let result = null
let targetType = checkType(target)

// 1.判断数据类型
if (targetType === 'Array') { // 是数组
result = []
} else if (targetType === 'Object') { // 是对象
result = {}
} else { // 是基本数据类型
return target
}

// 2.一个一个拷贝
for(let i in target) {
let value = target[i]
result[i] = clone(value) // 递归克隆每一项值
}
return result
}