js 深拷贝浅拷贝

js 专栏收录该内容
5 篇文章 0 订阅

1.简述

1.深/浅拷贝都是针对于引用类型而言
2.深拷贝是真正的拷贝出一个新的引用对象
3.浅拷贝是简单复制被拷贝对象的引用地址
4.修改拷贝对象或者修改被拷贝对象,另一个都会随着改变

2.深拷贝

2.1 什么是深拷贝

  • 拷贝整个对象(包括值+引用地址)成一个全新的对象

2.2 深拷贝的几种方法

2.2.1 JSON.stringify/parse

  • json.stringify()
    • 将JavaScript值转为json字符串
  • json.parse()
    • 将json字符串转为json对象或者JavaScript值

2.2.2 递归遍历对象,拷贝每一个属性并赋值(简单版)

参考链接: JavaScript基础心法——深浅拷贝

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;
}

const originObj = {a:'a',b:'b',c:[1,2,3],d:{dd:'dd'}};
const cloneObj = deepClone(originObj);
console.log(cloneObj === originObj); // false

cloneObj.a = 'aa';
cloneObj.c = [1,1,1];
cloneObj.d.dd = 'doubled';

console.log(cloneObj); // {a:'aa',b:'b',c:[1,1,1],d:{dd:'doubled'}};
console.log(originObj); // {a:'a',b:'b',c:[1,2,3],d:{dd:'dd'}};

2.2.2 递归遍历对象,拷贝每一个属性并赋值(复杂版)

  • 上面的方法会有很多问题,比如会出现循环引用情况下就报错,多个类型不能正确处理等情况,推荐参考下面这两个分析很详细

参考链接: 005:如何写一个完整的深拷贝?

参考链接: 深浅拷贝原理

3.浅拷贝

3.1 什么是浅拷贝

  • 直接复制( = 赋值操作即可)引用给另一个对象

  • 修改一个对象,另一个对象也会改变(因为指向同一个内存地址,改变的自然是同一个对象

      const originArray = [1,2,3,4,5];
      const originObj = {a:'a',b:'b',c:[1,2,3],d:{dd:'dd'}};
      const cloneArray = originArray;
      const cloneObj = originObj;
    
      console.log(cloneArray); // [1,2,3,4,5]
      console.log(originObj); // {a:'a',b:'b',c:Array[3],d:{dd:'dd'}}
      
      cloneArray.push(6);
      cloneObj.a = {aa:'aa'};
      
      console.log(cloneArray); // [1,2,3,4,5,6]
      console.log(originArray); // [1,2,3,4,5,6]
      
      console.log(cloneObj); // {a:{aa:'aa'},b:'b',c:Array[3],d:{dd:'dd'}}
      console.log(originArray); // {a:{aa:'aa'},b:'b',c:Array[3],d:{dd:'dd'}}
    

3.2 浅拷贝的几种方法

3.2.1 直接=赋值

  • 赋值操作其实本质上不涉及浅拷贝,因为是直接将一个对象的引用复制给另一个对象,因为指向同一个内存地址,肯定会互相影响
  • 手工实现一种简单浅拷贝赋值(针对引用类型浅拷贝,基本数据类型无影响
var simpleClone = function(obj){
	if(obj instanceof Object){
		let objClone = Array.isArray(obj) ? [] : {};
		for (let prop in obj){
			objClone[prop] = obj[prop];
		}
		return objClone;
	}else{
		return obj
	}
}

3.2.2 Object.assign(target,…source)(针对属性为引用类型浅拷贝,基本数据类型无影响

3.2.3 slice(针对属性为引用类型浅拷贝,基本数据类型无影响

3.2.4 ES6 …展开操作符(针对属性为引用类型浅拷贝,基本数据类型无影响

3.2.5 array.concat(针对属性为引用类型浅拷贝,基本数据类型无影响

  • 0
    点赞
  • 0
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值