Js中深克隆与浅克隆的实现原理

本文探讨了在JavaScript开发中复制对象的需求,详细解释了浅克隆和深克隆的概念。通过实例展示了浅克隆如何仅复制对象的表面属性,而深克隆则能确保新对象与其原型完全独立。文章还提供了实现这两种克隆方法的代码示例,强调当对象包含引用类型如数组或对象时,深克隆的重要性。
摘要由CSDN通过智能技术生成

前言

我们在项目开发中经常会遇到复制一个对象进行相关业务开发的情况,要求新对象和原来的对象一模一样,而开发时对对象进行操作又不能影响原对象。那么怎么实现呢?本文就带你研究一下克隆对象的实现与原理。

浅克隆

概念是很枯燥的,我们用案例解释吧。

var jack = {
  age: 25,
  gender: "男"
}
//要求复制一个对象jackCopy,里面的属性和值与jack一模一样

有人会说那还不简单,你看

var jackCopy = jack;
console.log(jackCopy);
//输入的jsckCopy和jack一模一样

那你可以把jackCopy的age改变为20,再判断一下jack==jackCopy的值,然后输出一下jack试试

jackCopy.age = 20;
console.log(jack);
console.log(jack==jackCopy);

你会发现jack的age也变为20了,jack==jackCopy为true,为什么呢?首先jack是引用类型,不是原始数据类型,jack变量里存的是指向{age:25,gender:“男”}的地址值,jackCopy = jack 只是把地址值复制了一份给jackCpoy(按值传递),也就是说jackCopy和jack都通过相同的地址引用着{age:25,gender:“男”},他们俩是一个对象,这就不是克隆了。

浅克隆实现

var jack = {
  age: 25,
  gender: "男"
};
function clone(obj){
  var newObj = {};
  for(var key in obj){
    newObj[key] = obj[key];
  }
    return newObj;
}
var jackCopy = clone(jack);
console.log(jackCopy);
console.log(jackCopy==jack);

输出jackCopy和jack一样,并且jackCopy==jack为false,实现了克隆。但上面的clone()函数实现克隆时,如果克隆的对象中的属性也是引用类型的话就不会再进一步克隆了。比如我们在jack中增加属性address

var jack = {
  age:25,
  gender:"男",
  address:{
    province:"河南",
    city:"周口"
  }
};
function clone(obj){
  var newObj = {};
  for(var key in obj){
    newObj[key] = obj[key];
  }
    return newObj;
}
var jackCopy = clone(jack);
jackCopy.address.province = "上海";
console.log(jack.address);
console.log(jackCopy.address==jack.address);

我们发现修改jackCopy的address后jack的address也会跟着改变,又回到了原来的问题,jackCopy.address和jack.address同时引用着一个对象,因此我们并没有实现完全克隆,clone()函数只是实现了浅克隆,下面我们来实现深克隆。

深克隆

var jack = {
  age:25,
  gender:"男",
  address:{
    province:"河南",
    city:"周口"
  },
  friend:["tom","rose","bob"]
};
function deepClone(obj){
  //如果对象是null
  if(obj===null){
    return null;
  }else if({}.toString.call(obj)==="[object Array]"){
    //如果对象是数组
    var newArr = [];
    newArr = obj.slice();//全部截取obj数组到newArr中
    return newArr;
  }
  var newObj = {};
  for(var key in obj){
    // 如果原对象的当前属性是原始值
    if(typeof obj[key]!=="object"){
      newObj[key] = obj[key]
    }else{
      // 如果当前属性还是引用类型就再次调用deepClone()函数
      newObj[key] = deepClone(obj[key])
    }
  }
  return newObj;
}
var jackCopy = deepClone(jack);
jackCopy.address.province = "上海";
console.log(jack);
console.log(jackCopy);

这就实现了深克隆,这个例子我们又给jack对象加了一个数组属性,因为数组复制时和对象不一样,不能用for in遍历,我们需要把数组和对象区分出来分别复制。

总结

  1. 如果一个对象中的属性都是原始类型的值,不再包含对象、数组等引用类型,我们可以用浅克隆进行复制。
  2. 如果一个对象包含内嵌的对象或者是数组的话,我们必须需要使用深克隆对它进行深层复制。

欢迎交流,个人博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值