在上节我们说到引用数据类型,由于他的存储机制比较特殊,不能够直接赋值,所以我们需要实现拷贝,就要创建一个新的对象,然后遍历原对象,将原对象的键名与键值赋给新对象,代码如下:
function clone(obj) {
let result
if (result instanceof Array) {
result = []
} else {
result = {}
}
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
result[key] = obj[key]
}
}
}
但是这样有一个问题,当对象中包含对象或数组时,则只能实现一层的拷贝,无法做到每一层都拷贝,所以我们就需要深拷贝,代码如下:
function deepClone(obj) {
// 递归的终止条件,当 参数obj 不是一个对象或数组,说明已经到最底层,不需要再执行,直接返回
if (typeof obj !== 'object' || obj == null) {
return obj
}
// 定义一个 result,当 参数obj 为数组时 result 就为 数组,当参数为对象时 result 就为 对象
let result
if (obj instanceof Array) {
result = []
} else {
result = {}
}
// 遍历 参数obj
for (let key in obj) {
// 判断属性是否为 参数obj 的属性,而不是原型属性
if (obj.hasOwnProperty(key)) {
// 将 参数obj 进行递归,并把最终得到的键名与键值赋给 result,
result[key] = deepClone(obj[key])
}
}
// 返回最终的到的 result
return result
}
这就是深拷贝的全部代码,并不是很长,同学们先理解,然后再敲上几遍基本就能熟悉了,在代码中有两处用到了数据类型的判断,在下节课我们来聊聊数据类型的判断