js 浅拷贝和深拷贝

深复制和浅复制只针对像 Object, Array 这样的复杂对象的。简单来说,浅复制只复制一层对象的属性,而深复制则递归复制了所有层级

一、浅拷贝(一层):仅仅是复制了引用,彼此之间的操作会互相影响

1. Object.assign
// Object.assign() 只复制源对象中可枚举的属性和对象自身的属性
let obj = { a:1, arr:[2,3]};
let res = Object.assign({}, obj)
2. 扩展运算符
let obj = { a:1, arr:[2,3]};
let res = {...obj};
3. 浅拷贝原生实现
const shallowCopy = (sourceObj) => {
  if (typeof sourceObj !== 'object') return;
  let newObj = sourceObj instanceof Array ? [] : {};
  
  for(let key in sourceObj){ 
    if(sourceObj.hasOwnProperty(key)) {
      //只复制元素自身的属性,不复制原型链上的
      newObj[key] = sourceObj[key];
    }
  }
  return newObj;
}
let obj = { a:1, arr:[2,3]};
let res = shallowCopy(obj);
// 浅复制只会将对象的各个属性进行依次复制,并不会进行递归复制

二、深拷贝(多层):在堆中重新分配内存,不同的地址,相同的值,互不影响

1. JSON 序列化
// 1.JSON.stringify():把一个 js 对象序列化为一个 JSON 字符串
// 2.JSON.parse():把 JSON 字符串反序列化为一个 js 对象
let a = {
    age: 1,
    jobs: {
        first: 'FE'
    }
}
let b = JSON.parse(JSON.stringify(a))
/**
 *缺点
 *1. 会忽略 undefined
 *2. 不能序列化函数(会忽略函数)
 *3. 不能解决循环引用的对象
 *优点 => 是内置函数中处理深拷贝性能最快的
 */
2. 深拷贝的原生实现
const deepCopy = (sourceObj) => {
  if(typeof sourceObj !== 'object') return;
  let newObj = sourceObj instanceof Array ? [] : {};
  
  for(let key in sourceObj){
    if(sourceObj.hasOwnProperty(key)) {
     //只复制元素自身的属性,不复制原型链上的
      newObj[key] = (typeof sourceObj[key] === 'object' ? deepCopy(sourceObj[key]) : sourceObj[key]);
     }
   }
   return newObj;
}

//深复制不仅将原对象的各个属性逐个复制出去,而且将原对象各个属性所包含的对象也依次采用深复制的方法递归复制到新对象上

三、Array 中的拷贝

1. Array.prototype.slice()
let a = [1, 2, 3, 4];
let b = a.slice();
2. Array.prototype.concat()
let a = [1, 2, 3, 4];
let b = a.concat();
Array 的 slice 和 concat 方法并不是真正的深拷贝,对于 Array 的第一层的元素是深拷贝,而 Array 的第二层 slice 和 concat 方法是复制引用。所以,Array 的 slice 和 concat 方法都是浅拷贝。
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值