Js基础知识-手动实现深拷贝

本文将手动实现引用类型的深拷贝
关于值类型与引用类型可阅读下方文章:
JS基础类型直通车:
Js基础知识-变量类型
Js基础知识-typeof运算符

let obj1={
  name:'王',
  age:23,
  address:{
    city:'河南省郑州市'
  },
  hobby:['play','eat']
}
let obj2=obj1
console.log(obj1.name) // 王
obj2.name='李'
console.log(obj1.name) // 李

由于直接将obj1直接赋值给了obj2,此时他们的指针地址是相同的,所以当obj2改变时,obj1的值也会改变。

如何将obj1赋值给obj2,修改obj2的值obj1得值不会改变?

  • 创建方法deepClone,将返回一个值作为方法的返回值
/**
* 深度克隆
* @param {object} obj 需要克隆的对象/数组
*/
function deepClone(obj={}){
    return  obj
}
  • 检查传入的参数类型是否为引用类型,不是的话将参数直接返回
/**
* 深度克隆
* @param {object} obj 需要克隆的对象/数组
*/
function deepClone(obj={}){
  if(typeof obj!=='object'||obj==null){
    return  obj
  }
}
  • 处理参数为引用类型,检查是否为数组,定义新的变量
/**
* 深度克隆
* @param {object} obj 需要克隆的对象/数组
*/
function deepClone(obj={}){
  if(typeof obj!=='object'||obj==null){
    return  obj
  }
  let result  // 将要返回的变量
  if(obj instanceof Array){
    result=[]   // 如果Obj为数组,则将返回定义为空数组
    }else{
    result={} // 如果Obj为对象,则将返回定义为空对象
  } 
}
  • 遍历赋值

会用到递归,如果不清楚可以将每一个obj的值进行打印。

/**
* 深度克隆
* @param {object} obj 需要克隆的对象/数组
*/
function deepClone(obj={}){
  if(typeof obj!=='object'||obj==null){
    return  obj
  }
  let result  // 将要返回的变量
  if(obj instanceof Array){
    result=[]   // 如果Obj为数组,则将返回定义为空数组
    }else{
    result={} // 如果Obj为对象,则将返回定义为空对象
  } 
 // forin可以用于对象和数组的遍历
    for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
       result[key]=deepClone(obj[key]) // 使用递归
    }
  }
}
  • 再次声明测试
/**
* 深度克隆
* @param {object} obj 需要克隆的对象/数组
*/
function deepClone(obj={}){
  console.log(obj)
 //obj每次的值
 //王     23     {city: "河南省郑州市"}      河南省郑州市      ["play", "eat"]     play       eat
  if(typeof obj!=='object'||obj==null){
    return  obj
  }
  let result  // 将要返回的变量
  if(obj instanceof Array){
    result=[]   // 如果Obj为数组,则将返回定义为空数组
    }else{
    result={} // 如果Obj为对象,则将返回定义为空对象
  } 
 // forin可以用于对象和数组的遍历
    for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
       result[key]=deepClone(obj[key]) // 使用递归
    }
  }
  return result
}
let obj2=deepClone(obj1)
obj2.name='李'
console.log(obj1.name,obj2.name) // 王 李

经过手动实现深度拷贝后就会发现,当改变obj2的值后,obj1并不会发生改变。

上一章 : Js基础知识-typeof运算符

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容