首页 > 其他分享 >理解深浅拷贝

理解深浅拷贝

时间:2022-08-26 17:47:33浏览次数:172  
标签:obj1 obj2 对象 数据类型 JSON 理解 深浅 拷贝

 

拷贝不能脱离数据类型来谈

数据类型

  除ES6引入的Symbol和BigInt数据类型,JS数据可大致分为:基本数据类型(String、 Number、Boolean、Null、Undefined)和引用数据类型(统称为Object,包括Array、Function...)。

  • 基本数据类型的特点:直接存储在栈(stack)中的数据。

  • 引用数据类型的特点:存储的是该对象在栈中引用,真实的数据存放在堆内存里。

  引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实体。

浅拷贝

这里有两个注意点:

  • 引用数据类型:对象,数组,函数等,这些拷贝的是地址。
  • 基本数据类型:数字,字符串,布尔值这些是拷贝值。

赋值是浅拷贝

比如我们定义一个变量为 obj1 的对象,然后我们把他赋值给另一个变量obj2,这个过程就会涉及到浅拷贝问题,另一个变量只是之前变量的一份拷贝,前后两个变量的存储地址是公用的。改变obj2的属性值,obj1的属性值也会发生改变。你可以这么认为,赋值实际上是将地址绑定在一起。

var obj1 = {
    a: 1,
    b: { f: { g: 1 } },
    c: [1, 2, 3]
};
let obj2 = obj1; 
obj2.b.f.g = 2; 
console.log(obj1, obj2);

这里得注意一下,Array类提供的API:concat、slice是返回一个浅拷贝。这两个方法都会返回一个新数组,所以一开始误以为这是属于深拷贝的,其实不然。MDN中关于它们的描述非常清楚:这两个方法不会改变 this 或任何作为参数提供的数组,而是返回一个浅拷贝,它包含与原始数组相结合的相同元素的副本。

深拷贝

深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。

JSON.parse(JSON.stringify())

var obj1 = {
    a: 1,
    b: { f: { g: 1 } },
    c: [1, 2, 3]
};
let obj2 = JSON.parse(JSON.stringify(obj1)); 
obj2.b.f.g = 2; 
console.log(obj1, obj2);

原理: 用JSON.stringify将对象转成JSON字符串,再用JSON.parse()把字符串解析成对象,一去一来,新的对象产生了,而且对象会开辟新的栈,实现深拷贝。

这种方法虽然可以实现数组或对象深拷贝,但不能处理函数。因为JSON.stringify() 方法是将一个JavaScript值(对象或者数组)转换为一个 JSON字符串,不能接受函数。

函数库lodash

该函数库也有提供_.cloneDeep用来做 Deep Copy。

require('lodash') 是nodejs里面的写法,在HTML中引用应该使用<script src=''lodash.js''>标签引入。

var _ = require('lodash');
var obj1 = {
    a: 1,
    b: { f: { g: 1 } },
    c: [1, 2, 3]
};
var obj2 = _.cloneDeep(obj1);
obj2.b.f.g = 2;
console.log(obj1, obj2);

除此之外,还有一种方法就是手写递归

通过遍历对象、数组不断进行拷贝,直到里边都是基本数据类型。

具体代码及分析过程,请看我后续写的 '理解并手写深拷贝函数'

 

标签:obj1,obj2,对象,数据类型,JSON,理解,深浅,拷贝
From: https://www.cnblogs.com/qingshuihongye/p/16628365.html

相关文章

  • 编译原理中的词法和语法分析怎么理解?
    看了一些编译原理的博文,对词法和语法的理解:  词法:是对一堆代码的一种提取,语法:是理解提取后的代码分别代表了什么意思,并赋予对应的意义,从而构建AST抽象语法树。......
  • 深入理解JUC:第六章:Semaphore信号灯
    理论:Semaphore是synchronized的加强版,作用是控制线程的并发数量多个线程抢多个资源,下面案例是有六台车抢三个停车位使用Semaphore的代码:publicclassDemo{......
  • 消息摘要(数字摘要)的理解 - 查看很多资料后的感悟
    Java密码技术-02-消息摘要(数字摘要)在开发过程中经常会遇到MD5、SHA1、SHA256等词语,这些是加密算法吗?严格意义上讲,这些并不是加密算法,而是消息摘要算法。咱就用人听......
  • 长链剖分以及对剖分的理解
    https://www.cnblogs.com/maoyiting/p/14178833.html#/cnblog/works/article/14178833目前接触到的重链剖分,长链剖分,实链剖分里面都有一些共同的性质吧!比如,每个点仅存在......
  • 22/8/25 深入理解计算机系统第九章 虚拟内存
    9.7案例:IntelCorei7/Linux内存系统见书5769.8Linux虚拟内存系统与进程相关的数据结构(比如:页表、task和mm结构、内核栈)对每个进程不同物理内存内核虚拟内存......
  • Object.assign实现的是浅拷贝还是深拷贝?
    首先MDN官网中有一句写道:   assign()语法:Object.assign(target,...sources)target:目标对象,接收源对象属性的对象,也是修改后的返回值。sources:源对象,包含将被......
  • 面经-并发-对ThreadLocal(线程隔离)的理解
    ThreadLocal作用:1.线程隔离。线程间:ThreadLocal可实现资源对象的线程隔离,让每个线程各用各的资源对象,避免争用引发的线程安全问题。2.资源共享。线程内:ThreadLocal同时实......
  • 824笔记(闭包,递归,浅/深拷贝)
    闭包闭包:有权访问另一个函数作用域中变量的函数,一个作用域可以访问另外一个函数内部的局部变量作用:延伸了变量的作用范围特性:变量或者参数不会被垃圾回收机制回收函......
  • 深入理解计算机系统 pdf
    高清扫描版下载链接:https://pan.baidu.com/s/11HBPtpCdG9zg3scgB_dBTw点击这里获取提取码对于计算机系统的分析已经很明了,可是人们是否真正清晰地理解?有本经典的图书描......
  • 时间复杂度的理解和计算
    时间复杂度的理解和计算前言:重在记录,可能出错。一、算法执行时间的表示  研究一个算法,我们先给出条件——忽略硬件的影响、忽略待处理数据的具体值,那么显而易得的,不同......