• 浅拷贝和深拷贝


    1.前言:数据类型

    数据类型分为基本数据类型和引用数据类型,理解这两种数据类型的特点,对理解深拷贝和浅拷贝至关重要

    1.1 基本数据类型

    基本数据类型:Boolean、Null、Undefined、Number、String、BigInt、Symbol
    基本数据类型都是存储在栈(stack)内存中,栈具有先进后出的特点,基本数据类型占用空间小、大小固定,通过按值来访问,属于被频繁使用的数据。

    let a=1;
    let b=a;
    a=3;
    console.log(a,b)
    
    • 1
    • 2
    • 3
    • 4

    输出结果:
    在这里插入图片描述
    基本数据类型的赋值,赋值后两个变量互不影响,b复制的是a的原始值,它们存储在独立的的栈空间中,因此修改了的值,b的值不会受到影响

    1.2 引用数据类型

    引用数据类型:Object(包括 Object 、Array 、Function)
    引用数据类型占据空间大、大小不固定,存放在栈中会有性能的问题。引用数据类型在栈中保存了一份指针,该指针指向对应的数据在堆中的起始地址,当解释器寻找引用值时,会首先检索其在栈中的地址,通过地址从堆中获得数据。

    obj={
     age:21
    }
    let objCopy=obj;
    objCopy.age=22;
    console.log(obj,objCopy)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述
    引用类型的赋值,在栈中复制了一份引用类型的地址指针,两个变量指向的还是同一个对象,所以修改objCopy.age时,obj.age也会改变

    2.浅拷贝和深拷贝

    2.1 浅拷贝

    浅拷贝是指,一个新的对象对原始对象的属性值进行精确地拷贝,如果拷贝的是基本数据类型,拷贝的就是基本数据类型的值,如果是引用数据类型,拷贝的就是内存地址。如果其中一个对象的引用内存地址发生改变,另一个对象也会发生变化。

    实现浅拷贝

    • Object.assign()
      Object.assign() 是ES6中对象的拷贝方法,接受的第一个参数是目标对象,其余参数是源对象,用法: Object.assign(target, source_1, ···) ,该方法可以实现浅拷贝,也可以实现一维对象的深
      拷贝。
    let target={a:1}
    let object1={b:2,c:3}
    Object.assign(target,object1)
    console.log(target)//{a:1,b:2,c:3
    
    • 1
    • 2
    • 3
    • 4
    • 扩展运算符
    let obj1 = {a:1,b:{c:1}}
    let obj2 = {...obj1};
    obj1.a = 2;
    console.log(obj1); //{a:2,b:{c:1}}
    console.log(obj2); //{a:1,b:{c:1}}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 手写实现浅拷贝函数
    // 浅拷贝的实现;
    function shallowCopy(object) {
       	// 只拷贝对象
       	if (!object || typeof object !== "object") return;
       	// 根据 object 的类型判断是新建一个数组还是对象
       	let newObject = Array.isArray(object) ? [] : {};
       	// 遍历 object,并且判断是 object 的属性才拷贝
       	for (let key in object) {
       		if (object.hasOwnProperty(key)) {
       		      newObject[key] = object[key];
       		   }
       	}
       	return newObject;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    2.2 深拷贝

    深拷贝相对浅拷贝而言,如果遇到属性值为引用类型的时候,它新建一个引用类型并将对
    应的值复制给它,因此对象获得的一个新的引用类型而不是一个原有类型的引用,所以彼此的修改,互不影响。

    • JSON.stringify()
      JSON.parse(JSON.stringify(obj)) 是目前比较常用的深拷贝方法之一,它的原理就是利用JSON.stringify 将 js 对象序列化(JSON字符串),再使用 JSON.parse 来反序列化(还原) js 对
      象。这个方法可以简单粗暴的实现深拷贝,但是还存在问题,拷贝的对象中如果有函数,undefined,symbol,当使用过 JSON.stringify() 进行处理之后,都会消失。
    let obj2={
      a:1,
      b:{
        c:2
      }
    }
    let obj3 = JSON.parse(JSON.stringify(obj2));
    obj2.b.c=3;
    console.log(obj2)//{a:1,b:{c:3}}
    console.log(obj3)//{a:1,b:{c:2}}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 函数库lodash的_.cloneDeep方法
    var  _=require('lodash')
    let obj2={
     a:1,
     b:{
       c:2
     }
    }
    var obj4=_.cloneDeep(obj2);
    console.log(obj2.b===obj4.b)//false
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 手写实现深拷贝函数
    // 深拷贝的实现
    function deepCopy(object) {
       	if (!object || typeof object !== "object") return;
       	let newObject = Array.isArray(object) ? [] : {};
       	for (let key in object) {
       		if (object.hasOwnProperty(key)) {
       		  newObject[key] =typeof object[key] === "object" ? deepCopy(object[key]) : object[key];
           	}
       	}
       	return newObject;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
  • 相关阅读:
    16:第二章:架构后端项目:12:配置mybatis;(在【imooc-news-dev-service-user】这个微服务子工程上,配置)
    pytorch,numpy两种方法实现nms类间+类内
    Unity中国成立,以应对国内日益严格的数据处理法规
    浅谈java单元测试框架junit4/5
    政务服务一网通办云平台及智慧政务大数据资源中心建设方案
    美容商铺怎样使用自动化流程鼓励员工创新
    JAVA基础算法(6)----- 国际象棋 α 皇后问题
    基于AVR单片机的心电信号获取与分析
    【字符串函数内功修炼】strcpy + strcat + strcmp(一)
    数据中台基本概念
  • 原文地址:https://blog.csdn.net/CYL_2021/article/details/130910133