序言
深入了解JavaScript中的拷贝操作 在前面文章中我们了解了JavaScript中拷贝的两种概念,今天我们将要学习一下这两种拷贝的实现原理是怎样的,如果面试官叫我们手写这两种拷贝你会吗,或者不熟悉忘记了,那么我们再来学习或者温故一遍吧!
手写浅拷贝
编写遍历实现浅拷贝的函数
首先,我们需要一个函数,该函数能够接受一个对象作为参数,然后通过遍历该对象的属性,逐个复制到一个新的对象中。以下是一个简单的实现:
js
function shalldowCpoy(obj){
if(typeof obj !== 'object' || obj === null) return //只拷贝引用类型 去除number和null类型
let objCopy = obj instanceof Array ? []:{}
for(let key in obj){
if(obj.hasOwnProperty(key)){
objCopy[key] = obj[key] //不能obj.key 因为会将key读成字符串
}
}
return objCopy
}
在这个函数中我们首先判断传入的对象是什么类型,如果是number
类型或者null
类型则返回,只允许拷贝引用类型
,然后我们用正则判断该对象是一个object
类型还是array
类型,如果是数组则创建一个新数组对象,如果是object
类型则创建一个对象类型的objCopy
变量,然后遍历源对象身上的所有属性,并且复制到新对象身上中。
示例应用
让我们通过一个示例来演示这个浅拷贝函数的应用:
js
let obj = {
name:'啊伟',
age:18,
like:{
type:'coding'
}
}
let newObj = shalldowCpoy(obj)
obj.like = 'fishing'
console.log(newObj);
在这个例子中,obj
包含一个两个简单的属性和一个嵌套的对象。通过调用 shallowdowCopy
函数,我们创建了一个浅拷贝 newObj
。这个新对象保留了原始对象的结构,但只复制了属性的引用,所以当我们对原对象中的对象属性内容进行修改时,新对象也受到了影响。
限制和注意事项
了解了浅拷贝的实现原理,我们还需要注意的是,这种浅拷贝的方法有其限制。如果对象中有嵌套的对象
或数组
,仅复制了它们的引用,而不是递归复制
。此外,该方法无法处理包含特殊值
(如函数、undefined
等)的对象。
在实际应用中,根据需求和数据结构的复杂性,选择合适的拷贝方法是很重要的。如果需要更全面
的复制,可能需要考虑深拷贝方法
或使用第三方库
来实现更复杂的拷贝逻辑。
手写深拷贝
编写遍历实现深拷贝的函数
首先,我们需要一个函数,该函数能够接受一个对象作为参数,并遍历该对象的所有属性,逐层进行复制。以下是一个简单的实现:
js
function deepCopy(obj) {
if(typeof obj !== 'object' || obj == null) return
let objCopy = obj instanceof Array ? []:{}
for(let key in obj) {
if(obj.hasOwnProperty(key)){
if(obj[key] instanceof Object){ 判断// obj[key]是不是引用类型
objCopy[key] = deepCopy(obj[key]) //递归复制嵌套的对象或数组 对obj[key]进行深拷贝然后返回给objCopy[key]
}else{
objCopy[key] = obj[key]
}
}
}
return objCopy
}
这里我们首先检查传入的参数是否为对象,如果不是对象或为null,则直接返回该参数。接着,根据传入的对象是数组还是普通对象来创建一个新的空对象或数组 objCopy
。
然后,函数通过遍历源对象的属性,判断对象或者数组中遍历到的哪一个属性是否是对象,如果是则递归地调用 deepCopy
函数来复制嵌套的对象或数组,如果不是则直接赋值就行。这确保了每一层的对象都是独立复制的,而不是共享引用。
示例应用
让我们通过一个示例来演示这个深拷贝函数的应用:
js
let obj = {
name:'啊伟',
age:18,
like:{
type:'coding'
}
}
let newObj = deepCopy(obj)
obj.like.type = 'fishing'
console.log(newObj);
在这个例子中,originalObj
包含一个简单的属性和一个嵌套的对象。通过调用 deepCopy
函数,我们创建了一个深拷贝 deepCopiedObj
。这个新对象不仅保留了原始对象的结构,而且递归地复制了所有嵌套的对象,所以当我们对原对象中的对象属性内容进行修改时,新对象并没有受到影响。
注意事项
尽管遍历实现的深拷贝是一种常见而有效的方式,但在处理循环引用、特殊值等情况时需要格外小心。这个简单的实现可能对于一般的场景足够,但对于更复杂的应用,可能需要使用更为完善的深拷贝方法,或者考虑使用第三方库,如Lodash的cloneDeep
方法。深拷贝是一个相对复杂的操作,因此在实际应用中需要根据具体情况选择合适的方法。
结语
那么到了这里我们今天的文章就结束啦~
创作不易,如果感觉这个文章对你有帮助的话,点个赞吧♥
更多内容关于JSON的结构和方法你是否还记得?忘记了再来看一遍吧
博主的开源Git仓库: gitee.com/cheng-bingw...