我自己研究的JS深拷贝函数,大家看看可靠吗
函数源码,考虑对象、函数、symbol特殊处理一下,其他直接返回原始值
function deepClone(obj){
let newObj
if(typeof obj==='object'&&obj!==null){
if(obj instanceof Array){
newObj= obj.map(item=>deepClone(item))
}else{
newObj=Object.assign({},obj)
}
for (const key in obj){
if(obj.hasOwnProperty(key)){
newObj[key]= deepClone(obj[key])
}
}
}else if(typeof obj==='function'){
let fnBody=[]
fnBody= obj.toString().match(/\((.+)\)\{(.+)\}$/)
const args=fnBody.slice(1,fnBody.length-1)
newObj=new Function(args,fnBody[fnBody.length-1])
for (const key in obj){
if(obj.hasOwnProperty(key)){
newObj[key]= deepClone(obj[key])
}
}
}else if(typeof obj==='symbol'){
newObj=Symbol(obj.toString().match(/\((.+)\)/)[1])
}else{
return obj
}
return newObj
}
下面是测试代码
let obj={
name:'tom',
arr:[
{age:18},
{gender:'nan'},
{level:2},
{fn:function(a){console.log('1')},name:'jj'},
null,
undefined
],
level:1
}
obj.arr[3].fn.namea='ff'
const newObj1=deepClone(obj)
obj.arr[3].fn.namea='aa'
obj.arr[4]={four:4}
obj.arr.count=5
console.log(obj)
console.log(newObj1)
console.log(obj.arr[3].fn.namea)
console.log(newObj1.arr[3].fn.namea)
输出如下:
//obj
{
name: 'tom',
arr: [
{ age: 18 },
{ gender: 'nan' },
{ level: 2 },
{ fn: [Function], name: 'jj' },
{ four: 4 },
undefined,
count: 5
],
level: 1
}
//newObj
{
name: 'tom',
arr: [
{ age: 18 },
{ gender: 'nan' },
{ level: 2 },
{ fn: [Function], name: 'jj' },
null,
undefined
],
level: 1
}
//obj.arr[3].fn.namea函数属性
aa
//newObj.arr[3].fn.namea函数属性
ff
我测试起来倒是没有什么问题。