个人对赋值、浅拷贝和深拷贝的理解

简介: 个人对赋值、浅拷贝和深拷贝的理解

个人对赋值、浅拷贝和深拷贝的理解


术语

赋值

基本数据类型的赋值

对象数据类型的赋值

拷贝

浅拷贝

深拷贝


术语



基本数据类型:数字、字符串等这种。

对象数据类型:Object与Array这样的引用数据类型的。

赋值:可以看成等号连接,赋值的变量(等号左边)指向被赋值的变量(等号右边)


赋值



赋值看指向,觉得看字太累请直接理解代码。


基本数据类型的赋值



这里a的指向是一个1这个数字基本类型,

当b赋值2时等于是改变了b的指向,

b不指向a了,因此a不会改变

//这里a的指向是一个1这个数字基本类型
let a = 1;
//这里b赋值a指向a
let b = a;
//b不指向a了,指向2这个数字基本类型
b = 2;
console.log(a);//1
console.log(b);//2

对象数据类型的赋值


以下代码中,a赋值给b,对修改值与添加值,两个对象的内容完全一致

b和a指向同一个对象{},当b修改c添加d,但是没有对b直接进行赋值,因此

b还是指向a的,a内容也会同时改变

//a指向一个对象{ c: 1 }
let a = { c: 1 }
//b指向a
let b = a
console.log(a)//{ c: 1 }
console.log(b)//{ c: 1 }
//b修改指向的那个对象的内容
b.c = 2
b.d = 2
//由于b和a指向同一个对象{},因此b修改c添加d,a内容也会同时改变
console.log(a)//{ c: 2, d: 2 }
console.log(b)//{ c: 2, d: 2 }

拷贝



浅拷贝与深拷贝都是对赋值的不同用法。


浅拷贝



下面这段觉得写的花里胡哨可以先不看以后理解了再来看加深印象,我们可以跳过直接看代码和图。


浅拷贝只复制指向某个对象的指针,不复制对象本身。只拷贝对象空间,而不复制资源。新旧指针同时共享一块内存。所以当拷贝来的对象修改的是非对象的基本数据类型,由于是改变了对象本身而不是改变了复制来的指针指向的对象的内容,所以原对象不会改变,如果修改的是对象数据类型,则会改变原对象里的内容。常见实现方式:Object.assign()

let a = { c: 1, z: { y: 1 } }
let b = Object.assign({}, a)
console.log(a)//{ c: 1, z: { y: 1 } }
console.log(b)//{ c: 1, z: { y: 1 } }


浅拷贝就是对b新建了一个对象{c = a.c,z = a.z},对a里面的内容一一赋值到b

这里很关键,如果你对上文中提到的对象数据类型和基本数据类型的赋值有所理解就会知道

赋值c是基本数据类型的赋值,赋值z是对象数据类型的赋值


image.png

然后进行修改

let a = { c: 1, z: { y: 1 } }
let b = Object.assign({}, a)
console.log(a)//{ c: 1, z: { y: 1 } }
console.log(b)//{ c: 1, z: { y: 1 } }
//三个操作,基本数据类型的赋值,对象数据类型的赋值,基本数据类型的添加没有用到赋值
b.c = 2
b.z.y = 2
b.d = 2
//一一看赋值的属性
//b中的c是基本数据类型,原本指向a中的c,但是改变了指向指向了2
//b中的z是对象类型的赋值,修改的是和a中的z同一个对象,因此联动
//b中的d不是赋值来的,与a里面的内容无关
console.log(a)//{ c: 1, z: { y: 2 } }
console.log(b)//{ c: 2, z: { y: 2 } , d : 2 }

以上代码用图如何理解呢?当b对a进行浅拷贝时,等于b新建了一个空间,对a的内容属性逐一进行指针拷贝,如果遇到基本数据类型等于是深拷贝,遇到对象数据类型等于是赋值,因为a和b不是一个空间,因此b添加d属性不会影响到a。


image.png

深拷贝


深拷贝是通过复制创造避开赋值带来的连锁反应,创造一个完全一样的对象,两个对象不会引起关联与变化。常见实现方式:JSON.parse(JSON.stringify())。

回过头看我们的对象数据类型的赋值,如果我们的b的是创建来的,那么与a无关不会引发联动

let a = { c: 1 }
let b = { c: 1 }
console.log(a)//{ c: 1 }
console.log(b)//{ c: 1 }
b.c = 2
b.d = 2
//a没改变
console.log(a)//{ c: 1 }
console.log(b)//{ c: 2, d: 2 }

但是你会说这与深拷贝无关啊?拷贝过程呢?别急,如果你想拿a的数据来用啊,深拷贝是转变成字符串再转回对象,这个对象等于新建的,与a无关,这就是把a拿来深拷贝了。

let a = { c: 1 }
//用深拷贝,等同于let b = { c: 1 }
let b = JSON.parse(JSON.stringify(a))
console.log(a)//{ c: 1 }
console.log(b)//{ c: 1 }
b.c = 2
b.d = 2
//a没改变
console.log(a)//{ c: 1 }
console.log(b)//{ c: 2, d: 2 }
相关文章
|
6月前
|
存储 Cloud Native Linux
C++ 深拷贝浅拷贝
C++ 深拷贝浅拷贝
|
7月前
|
JSON Java API
深拷贝、浅拷贝
深拷贝、浅拷贝
20 0
|
17天前
什么是深拷贝和浅拷贝哇
什么是深拷贝和浅拷贝哇
|
4月前
|
消息中间件 Kubernetes NoSQL
构造函数、深拷贝、浅拷贝
构造函数、深拷贝、浅拷贝
|
8月前
|
编译器 C++
C++中的深拷贝和浅拷贝介绍
对于基本类型的数据以及简单的对象,它们之间的拷贝非常简单,就是按位复制内存。例如: class Base{ public: Base(): m_a(0), m_b(0){ } Base(int a, int b): m_a(a), m_b(b){ } private: int m_a; int m_b; }; int main(){ int a = 10; int b = a; //拷贝 Base obj1(10, 20);
91 0
|
10月前
深拷贝和浅拷贝
类里面会为我们实现默认的拷贝,这个做的是值的拷贝,但是假如对象里的数据成员在堆上开辟了内存资源,如果继续浅拷贝就会导致两根指针指向同一块资源,从而产生内存泄漏问题。但是深拷贝可以解决这个问题,本文将详细介绍深拷贝与浅拷贝。
|
JSON JavaScript 数据格式
js对象的直接赋值、浅拷贝与深拷贝
js对象的直接赋值、浅拷贝与深拷贝
122 0
js对象的直接赋值、浅拷贝与深拷贝
|
JavaScript 前端开发
数组和对象的浅拷贝,深拷贝
数组和对象的浅拷贝,深拷贝
数组和对象的浅拷贝,深拷贝
|
JSON 数据格式
5、浅拷贝与深拷贝
5、浅拷贝与深拷贝
89 0