Quickly understand JS depth and copy and use it immediately

Quick JS understanding of deep and shallow copy

自我记录

In layman's terms, copying means copying. Ps: This article is just a personal opinion and summary. If you have different opinions, you can point them out in the comment area and learn together! First of all, I want to understand, , I think I need to
know 深拷贝a 浅拷贝few 4knowledge points about JS basics 数据类型, 引用类型, ,
If you want to use it directly, you can directly Look 4.1, 4.2, 4.3(dark copy) The reason why there is so much ink is that we should not only be able to use it but also know some principles. It
4.1is ...the ES6 expansion operator (light),
4.2it is Object.assign(target,sources)the ES6 method (light),
4.3it is JSON.parse(JSON.stringify(对象))the serialization and deserialization method (deep)

1. JS data types

1.1 Basic data types (7)

1.Number(数值,包含NaN)
2.String(字符串)
3.Boolean(布尔值)
4.Undefined(未定义/未初始化)
5.Null(空对象)
6.Symbol(独一无二的值,ES6 新增)
7.BigInt (任意精度格式的整数,能够表示超过 Number 类型大小限制的整数,ES10新增)

1.2 Reference types

1.Object(包含Array、Function等)

1.3 Differences between basic data types and reference types

(1).Basic data type (stored in )

Basic data types refer to those stored in . They are stored 简单数据段,数据大小确定,内存空间大小可以分配directly , so they can be accessed directly.

(2).Reference type (stored in )

The reference data type is stored 指针(一个地址)in 指针指向堆the entity 起始地址. When the interpreter looks for a reference value, it first retrieves its address in the object, and then obtains the entity from the heap after obtaining the address.

2. Stack and heap in memory

2.1 What is a stack

First in, last out; automatically allocated and released by the operating system to store function parameter values, local variable values, etc. It operates like a stack in a data structure.

2.2 What is a heap?

Queue priority, first in first out; dynamically allocated space is generally allocated and released by the programmer. If the programmer does not release it, it may be reclaimed by the OS when the program ends. The allocation method is similar to a linked list.

2.3 Summary of differences

Personally, I understand it from the perspective of this article: 基本数据类型在栈里面存的是值, 引用类型在栈里面存的是一个指针(it feels like an address) is used to 指向对应堆里面的这个地址involve shallow copy and deep copy.

For detailed overview, please refer to other articles online.

3. Shallow copy and deep copy

1. Assignment 基本数据类型means 栈中的值copying is given, but what 引用类型is assigned is 栈中对应堆的的地址, and 不是堆中的数据. That is to say, the two objects point to the fact 同一个存储空间that no matter which object changes, it is actually the content of the changed storage space. Therefore, the two objects are linked. Once one party is modified, the other party will also be affected.
2. Therefore: there is no shallow/deep copy of basic data types

3.1 Shallow copy

As mentioned earlier, when defining an object or array, variables store only 一个地址. When we use object copy, if the attribute is 对象or 数组, what we pass at this time is only 一个地址. Therefore, when the child object accesses this attribute, it will trace back to the address pointed to by the parent object 堆内存中, that is, if the parent and child objects occur 关联, the attribute values ​​​​of both will be the same 指向同一内存空间联动.
Simple understanding: Shallow copy is to copy only one layer of data.
Common methods are: ...andObject.assign(target,sources)

3.2 Deep copy

An identical object will be created. The new object does not share memory with the original object, and modifications to the new object will not change the original object.

4. Three ways to share commonly used copies

4.1 ES6 spread operator (shallow copy)

There is no shallow copy as follows:

  // 没有进行深拷贝
  let a = [1, 2, 3]
  let b = a
  a[0] = 100
  console.log(a) // [100, 2, 3]
  console.log(b) // [100, 2, 3]

Use ...shallow copy as follows:针对只有一层数据

  // 进行浅拷贝
  let a = [1, 2, 3]
  let b = [...a]
  a[0] = 100
  console.log(a) // [100, 2, 3]
  console.log(b) // [1, 2, 3]

Multi-layer data structures such as two-dimensional arrays can only be modified by this method.第一层

  // 只拷贝了一层数据
  let a = [1, 2, 3, [40, 50]]
  let b = [...a]
  a[0] = 10
  a[3][0] = 400
  console.log(a)  // [10, 2, 3, [400, 50]]
  console.log(b)  // [1, 2, 3, [400, 50]]

4.2 ES6 Object.assign(target,sources)(浅拷贝)

There is no shallow copy as follows:

  // 没有进行深拷贝
  let a = [1, 2, 3]
  let b = a
  a[0] = 100
  console.log(a) // [100, 2, 3]
  console.log(b) // [100, 2, 3]

Use Object.assignshallow copy as follows:针对只有一层数据

  // 进行浅拷贝
  let a = [1, 2, 3]
  let b = Object.assign([], a)
  a[0] = 100
  console.log(a) // [100, 2, 3]
  console.log(b) // [1, 2, 3]

Multi-layer data structures such as two-dimensional arrays can only be modified by this method.第一层

  // 只拷贝了一层数据
  let a = [1, 2, 3, [40, 50]]
  let b = Object.assign([], a)
  a[0] = 10
  a[3][0] = 400
  console.log(a) // [10, 2, 3, [400, 50]]
  console.log(b) // [1, 2, 3, [400, 50]]


Insert image description here

If you want to avoid changes, you cannot share xx002. It can also be understood that the heap of b uses xx003 and xx004.
Insert image description here
Obviously the expansion operator cannot be implemented.

4.3 Serialization and deserialization method (deep copy)

JSON.parse(JSON.stringify(对象))

  let a = [1, 2, 3, [40, 50]]
  let b = JSON.parse(JSON.stringify(a))
  a[0] = 10
  a[3][0] = 400
  console.log(a, 'a') // [10, 2, 3, [400, 50]]
  console.log(b, 'b') // [1, 2, 3, [40, 50]]

4.4 Recursion (deep copy)

只考虑数据层面

 // 递归
 function fnDeepCopy(newObj, obj) {
    
    
     // 遍历对象
     for (key in obj) {
    
    
         // newObj[key] = obj[key] 拷贝一层
         // 如果obj[key] 是数组,又要重新遍历数组拷贝,在如果obj[key]是对象也要重新遍历拷贝,否则就直接拷贝一层
         if (obj[key] instanceof Array) {
    
    
             // 先判断数组,因为Array也是对象的一种
             newObj[key] = []
             fnDeepCopy(newObj[key], obj[key])
         } else if (obj[key] instanceof Object) {
    
    
             newObj[key] = {
    
    }
             fnDeepCopy(newObj[key], obj[key])
         } else {
    
    
             newObj[key] = obj[key]
         }
     }
 }

 let a = [1, 2, 3, [40, 50]]
 let b = []
 fnDeepCopy(b, a)
 a[0] = 10
 a[3][0] = 400
 console.log(a) // [10, 2, 3, [400, 50]]
 console.log(b) // [1, 2, 3, [40, 50]]

Insert image description here
It is not easy to summarize, but I hope it will be helpful to you. I hope we can learn and make progress together. (Likes and collections are my motivation) The above are the
two methods I commonly use.
By the way, I will share what a big guy said: deep js deep copy object: https ://www.jianshu.com/p/b08bc61714c7

Guess you like

Origin blog.csdn.net/zhgweb/article/details/130807952