js数组对象的深拷贝

js中的深拷贝

普通的数组,slice,concat或者es6的扩展运算符都可以实现深拷贝,但是如果是数组对象却不可以
例如:

[
    {name: 'A', count: 1},
    {name: 'B', count: 2},
    {name: 'C', count: 3},
    {name: 'D', count: 4},
    {name: 'E', count: 5},
]

有以下3种方式可以快速的实现

let start = [
    {name: 'A', count: 1},
    {name: 'B', count: 2},
    {name: 'C', count: 3},
    {name: 'D', count: 4},
    {name: 'E', count: 5},
]
let end = start.map(o => Object.assign({}, o));
let end = start.map(o => ({...o}));
let end=JSON.parse(JSON.stringify(start)) //此方法不推荐,因为:
//undefined,Function,Symbol 时,它被忽略掉
Infinity,NaN 会被变成 null
Date 对象会被转化为 String (默认调用date.toISOString())

但是呢,经过事实的检验我们发现,concat和slice只是对数组的第一层进行深拷贝,如果是[1,[1,2,3],{a:1}] 这种数组,就不行嘞。

同样的 … 实现的是对象第一层的深拷贝。后面的只是拷贝的引用值

而Object.assign()拷贝的是属性值。假如源对象的属性值是一个对象的引用,那么它也只指向那个引用。也就是说,如果对象的属性值为简单类型(如string, number),通过Object.assign({},srcObj);得到的新对象为深拷贝;如果属性值为对象或其它引用类型,那对于这个对象而言其实是浅拷贝的。

哎 弄了半天都不行呗,总结: 并没有简单快速又无敌的深拷贝!!

怎么办呢 只有递归喽
递归的思想就很简单了,就是对每一层的数据都实现一次 创建对象->对象赋值 的操作,简单粗暴上代码:

function deepClone(source){
  const targetObj = source.constructor === Array ? [] : {}; // 判断复制的目标是数组还是对象
  for(let keys in source){ // 遍历目标
    if(source.hasOwnProperty(keys)){
      if(source[keys] && typeof source[keys] === 'object'){ // 如果值是对象,就递归一下
        targetObj[keys] = source[keys].constructor === Array ? [] : {};
        targetObj[keys] = deepClone(source[keys]);
      }else{ // 如果不是,就直接赋值
        targetObj[keys] = source[keys];
      }
    } 
  }
  return targetObj;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值