前言
之前对深浅拷贝没有很多认识,一开始对深浅拷贝仅仅只是通过面试题或者一些掘金文章来认识的,所以在一段时间提起深浅拷贝仍旧是一个模糊的看法。其实深浅拷贝应用的范围很关,如果对于深浅拷贝没有一个很好的认识,在一些方面会很容易写出bug。
一开始在看深浅拷贝,仅仅记住就是浅拷贝是对于基本数据类型是不会影响到源对象,而引用类型就是拷贝的其地址值。而深拷贝就是完全拷贝源对象的键值对,修改一方不会修改到源对象。
浅拷贝原理
其实,浅拷贝如果仅仅认识到是对两种数据类型的处理,那么对于区分深拷贝是会迷惑的,在一些API上面会区分不了这是浅拷贝还是深拷贝,我就对Object.assign是浅拷贝还是深拷贝迷惑了,其实浅拷贝很简单,就是按照字面意思理解,它是很简单的对对象进行拷贝,只完全拷贝了对象的一层属性值,但是这一层属性值是引用类型,那么就是拷贝的是其地址值。
这有很多运用到浅拷贝的API,如Object.assign,扩展运算...等。
手写浅拷贝
function shallowCopy (target) {
let result = Array.isArray(target) ? [] : {}
//遍历target
for (var key in target) {
//排除原型上的属性干扰
if (target.hasOwnProperty(key)) {
result[key] = target[key]
}
}
return result
}
深拷贝原理
深拷贝就是完全拷贝源对象,一层层遍历源对象的键值对,然后将其赋值到一个新的对象里,修改当前对象不会影响到源对象,因为当前对象和源对象不是保存同个地址值。
有一些方式可以实现深拷贝,如JSON.stringfy(只能拷贝对象的属性不能拷贝对象的方法和一些特殊值)、还有lodash也可以。
手写深拷贝
function deepClone(target, result) {
let result = result || {}
//遍历target
for (let key in target) {
//排除原型属性干扰
if (target.hasOwnProperty(key)) {
//引用类型就迭代
if (targer[key] !== null && typeof target[key] === 'object') {
result = Array.isArray(target[key])? [] : {}
deepClone(target[key], result[key])
} else {
//基本数据类型就直接复制
result[key] = target[key]
}
}
}
}