引言
在上一篇文章中,我们聊到了深拷贝和浅拷贝,不知道的掘友们可以去看 (不知深浅的拷贝),在这篇文章中,我将带领大家手写深拷贝和浅拷贝!
浅拷贝
//浅拷贝的实现原理
let obj = {
name:'www',
age:18,
like:{
type: 'coding'
}
}
let arr = [1,'a',null]
function shalldowCopy(obj){
//类型判断
if(typeof obj !== 'object' || obj == null) return
let objCopy = obj instanceof Array ? []:{}
for(let key in obj){
if(obj.hasOwnProperty(key)){
objCopy[key] = obj[key]
}
}
return objCopy
}
let newObj = shalldowCopy(obj)
obj.like.type = 'sleeping'
console.log(newObj.like.type);//sleeping
我们这里实现的是数组和对象的浅拷贝
1 .我们可以在方法中看到在12行我们先判断了传进来的obj是否不为对象或者obj为null,这样我们就可以确保传入的obj为对象或者数组,如果有掘友对于类型判断仍心存疑虑,可以去看这篇文章"探秘JavaScript:类型判断的奇妙世界(一)" 。
2 .在判断完以后,我们用到了一个三目运算符,将objCopy 定义为传入的obj类型。
3 .在第14行,我们开始用 for in 方法遍历obj,for in 方法有一个缺点,就是可能会遍历到不属于obj的属性,所以我们在for in中进行判断,如果key为obj中的属性,则在objCopy中创建一个同样的属性并赋值。
4.在22行改变obj.like.type的值,在23行打印发现newobj.like.type也随之改变,我们的浅拷贝就写好了
深拷贝
//手动实现深拷贝
let obj = {
name:'www',
age:18,
like:{
type: 'coding'
}
}
function deepCopy(obj){
let objCopy = {}
for(let key in obj){
if(obj.hasOwnProperty(key)){
if(obj[key] instanceof Object){
objCopy[key] = deepCopy(objCopy[key])
}else{
objCopy[key] = obj[key]
}
}
}
return objCopy
}
这里的代码仅实现了对象的深拷贝,对于数组如何进行深拷贝,相信你看完这段代码就会有些思路了
前面的思路和浅拷贝一模一样,在第13行开始改变,我们来想想,浅拷贝和深拷贝的区别在哪里?因为在拷贝中向新数组传入了地址,导致浅拷贝,那么我们就要在新对象中避免传入地址。我们在第13行判断obj[key]是否为一个对象,如果为对象,那么我们运用递归再调用deepCopy,反之则直接复制。 最后我们返回的结果将不会再有原对象中的地址,那么一个简单的对象深拷贝就写完了。
结尾
在面试的时候,可能会被面试官要求手写浅拷贝和深拷贝,希望掘友们看完这篇文章能有所收获,从容面对开发和面试!