The goddess of town building

preface

Want to write a good front, first practice good internal skills.

Stack memory and heap memory, shallow copy and deep copy, can be said to be the front-end programmer’s internal work, to know how, know why.

The author wrote the beauty of JavaScript data structure and algorithm series with the language is JavaScript, aimed at the introduction of data structure and algorithm and convenient later review.

The stack

define

  1. Last come first out, first come first outLast in, first outLIFO, this is typicalThe stackStructure.
  2. New elements added or to be removed are stored at the end of the stack, calledTo the top of the stackAnd the other end is calledThe bottom of the stack.
  3. In the stack, the new elements are near the top of the stack, and the old elements are near the bottom of the stack.
  4. From the operation characteristics of the stack, is aOperation is restrictedAllows data to be inserted and deleted at one end only.
  5. A stack that does not contain any elements is calledAn empty stack.

Stacks are also used in programming language compilers and in memory to hold variables, method calls, etc., such as function call stacks.

The heap

define

  • The heap data structure is a tree structure. It accesses data in much the same way as a bookshelf or a book. We don’t care what order the books are placed in, as long as we know the name of the book we can take out the book we want. For example, in JSON format data, the key-value we store can be unordered. As long as we know the key, we can extract the value corresponding to the key.

Heap vs. stack comparison

  • The heap is dynamically allocated memory, which varies in size and is not automatically freed.
  • The stack automatically allocates a relatively fixed size of memory space and is automatically released by the system.
  • Stack, linear structure, last in first out, easy to manage.
  • Heap, a chaotic, cluttered, convenient storage and open up memory space.

Stack memory vs. heap memory

Variables in JavaScript are divided into primitive types and reference types.

  • Basic types are simple data segments that are stored in stack memory. Their values have a fixed size, are stored in stack space, accessed by value, and are automatically allocated and released by the system. The benefit is that memory can be reclaimed in a timely manner, making it easier to manage memory space compared to the heap. Boolean, Null, Undefined, Number, String, and Symbol in JavaScript are all basic types.

  • Reference types (such as objects, arrays, functions, etc.) are objects stored in the heap memory, and their value size is not fixed. The access address of the object stored in the stack memory points to the object in the heap memory. JavaScript does not allow direct access to the location in the heap memory. In JavaScript, Object, Array, Function, RegExp, and Date are reference types.

Combined with examples

leta1 = 0; / / stack memorylet a2 = "this is string"/ / stack memoryleta3 = null; / / stack memoryletb = { x: 10 }; // The variable b exists in the stack, and {x: 10} exists in the heap as an objectletc = [1, 2, 3]; // The variable c resides on the stack, and [1, 2, 3] resides on the heap as an objectCopy the code

When we want to access reference data types in heap memory

    1. Gets a reference to the object’s address from the stack
    1. And then we get the data we need from the heap

The base type is replicated

let a = 20;
letb = a; b = 30; console.log(a); / / 20Copy the code

When data replication occurs in stack memory, the system will automatically assign a new value to the new variable. Finally, these variables are independent of each other.

The reference type has been copied

let a = { x: 10, y: 20 }
letb = a; b.x = 5; console.log(a.x); / / 5Copy the code
  • The copy of the reference type also assigns a new value to the new variable B, which is stored in stack memory, except that this value is only an address pointer to the reference type.
  • They both point to the same value, that is, the address pointer is the same, and the concrete object that is accessed in the heap is actually the same.
  • So when you change b.x, A.x also changes, which is the nature of reference types.

Combined with the following figure

conclusion

Stack memory Heap memory
Store the underlying data types Store reference data types
According to the value of access Access by reference
Values stored are fixed in size Stored values vary in size and can be adjusted dynamically
The system automatically allocates memory space Assigned by code
Small space, high operating efficiency Large space, relatively low operating efficiency
First in, last out, last in, first out Unordered storage, which can be obtained by reference

Shallow copy and deep copy

A copy of the reference type described above is a shallow copy in which all access addresses point to the same memory space. So if I change the value of one, I change the value of the other.

Deep copy: The obtained access addresses point to different memory Spaces and are irrelevant to each other. So if you change one of these values, the other one doesn’t change.

When we use array copying, most of us use =, which is just a shallow copy and has a lot of problems. Such as:

letArr = [1, 2, 3, 4, 5];let arr2 = arr;
console.log(arr) //[1, 2, 3, 4, 5]
console.log(arr2) //[1, 2, 3, 4, 5]
arr[0] = 6;
console.log(arr) //[6, 2, 3, 4, 5]
console.log(arr2) //[6, 2, 3, 4, 5]
arr2[4] = 7;
console.log(arr) //[6, 2, 3, 4, 7]
console.log(arr2) //[6, 2, 3, 4, 7]
Copy the code

Obviously, in shallow copy, the copied and copied arrays will interact with each other.

So, there has to be a way to be unaffected, and that is deep copy.

The copying process of a deep copy

let a = { x: 10, y: 20 }
letb = JSON.parse(JSON.stringify(a)); b.x = 5; console.log(a.x); // 10 console.log(b.x); / / 5Copy the code

An array of

The for loop

//forCircle the copyfunction copy(arr) {
    let cArr = []
    for(let i = 0; i < arr.length; i++){
      cArr.push(arr[i])
    }
    return cArr;
}
letArr3 = [1, 2, 3, 4];letArr4 = copy (arr3) / / [1, 2, 3, 4] the console log (arr4) / / [1, 2, 3, 4] arr3 [0] = 5; The console. The log (arr3) / / [5, 2, 3, 4] the console. The log (arr4) / / [1, 2, 3, 4]Copy the code

Slice method

// Slice implements deep copyletArr5 = [1, 2, 3, 4];letarr6 = arr5.slice(0); arr5[0] = 5; console.log(arr5); / / (5, 2, 3, 4] the console. The log (arr6); / / [1, 2, 3, 4]Copy the code

Concat method

//concat implements deep copyletArr7 = [1, 2, 3, 4];letarr8 = arr7.concat(); arr7[0] = 5; console.log(arr7); / / (5, 2, 3, 4] the console. The log (arr8); / / [1, 2, 3, 4]Copy the code

4. Es6 extended operation

// Es6 extended operations implement deep copyletArr9 = [1, 2, 3, 4];let[...arr10] = arr9; arr9[0] = 5; The console. The log (arr9) / / [5, 2, 3, 4] the console. The log (arr10) / / [1, 2, 3, 4]Copy the code

Parse with json.stringify

letArr9 = [1, 2, 3, 4];letarr10 = JSON.parse(JSON.stringify(arr9)) arr9[0] = 5; The console. The log (arr9) / / [5, 2, 3, 4] the console. The log (arr10) / / [1, 2, 3, 4]Copy the code

Note: This method may have performance problems when the amount of data is large.

object

Object loop

// Loop over the copy objectlet obj = {
    id:'0',
    name:'king',
    sex:'man'
}
let obj2 = copy2(obj)
function copy2(obj) {
    let cObj = {};
    for(var key in obj){
      cObj[key] = obj[key]
    }
    return cObj
}
obj2.name = "king2"
console.log(obj) // {id: "0", name: "king", sex: "man"}
console.log(obj2) // {id: "0", name: "king2", sex: "man"}
Copy the code

Json. parse and json.stringify

var obj1 = {
    x: 1, 
    y: {
        m: 1
    },
    a:undefined,
    b:function(a,b){
      return a+b
    },
    c:Symbol("foo")}; var obj2 = JSON.parse(JSON.stringify(obj1)); The console. The log (obj1) / / {x: 1, y:} {m: 1, a: undefined, b: ƒ, c: Symbol (foo)} the console. The log (obj2) / / {x: 1, y: {m: 1}} obj2.y.m = 2; Log (obj1) //{x: 1, y: {m: 1}, a: undefined, B: ƒ, C: Symbol(foo)} console.log(obj2) //{x: 2, y: {m: 2}}Copy the code

Deep copy of multidimensional objects can be realized.

Note: during json.stringify () serialization, undefined, arbitrary functions, and symbol values are ignored during serialization (when appearing in property values of non-array objects) or converted to NULL (when appearing in arrays).

Es6 extended operation

let obj = {
    id:'0',
    name:'king',
    sex:'man'
}
let{... obj4} = obj obj4.name ="king4"
console.log(obj) //{id: "0", name: "king", sex: "man"}
console.log(obj4) //{id: "0", name: "king4", sex: "man"}
Copy the code

Four, the Object. The assign ()

Object.assign() can only implement deep copies of one-dimensional objects.

var obj1 = {x: 1, y: 2}, obj2 = Object.assign({}, obj1); console.log(obj1) // {x: 1, y: 2} console.log(obj2) // {x: 1, y: 2} obj2.x = 2; X console.log(obj1) {x: 1, y: 2} console.log(obj2) {x: 2, y: 2} var obj1 = {x: 1, y: 2}}; var obj2 = Object.assign({}, obj1); console.log(obj1) // {x: 1, y: {m: 1}} console.log(obj2) // {x: 1, y: {m: 1}} obj2.y.m = 2; / / modify obj2. Y.m console. The log (obj1) / / {x: 1, y: {2} m:} the console. The log (obj2) / / {x: 2, y: {2} m:}Copy the code

Generic deep-copy methods

Simple version of

let clone = function (v) {
    let o = v.constructor === Array ? [] : {};
    for(var i in v){
      o[i] = typeof v[i] === "object" ? clone(v[i]) : v[i];
    }
    returno; } / / testlet obj = {
    id:'0',
    name:'king',
    sex:'man'
}
let obj2 = clone(obj)
obj2.name = "king2"
console.log(obj) // {id: "0", name: "king", sex: "man"}
console.log(obj2) // {id: "0", name: "king2", sex: "man"}

letArr3 = [1, 2, 3, 4];let arr4 = cloneArr3 // [1,2,3,4] arr3[0] = 5; The console. The log (arr3) / / [5, 2, 3, 4] the console. The log (arr4) / / [1, 2, 3, 4]Copy the code

The deep-copy method above, however, should be avoided because it gets caught up in a circular recursive process that results in a stack burst.

let obj1 = {
    x: 1, 
    y: 2
};
obj1.z = obj1;
let obj2 = clone(obj1);
console.log(obj2) 
Copy the code

The results are as follows:

Summary: A deep understanding of the depth of javascript copy, you can flexibly use arrays and objects, and can avoid a lot of bugs.

Article Output plan

The beauty of JavaScript data structures and algorithms series of articles, adhere to about 3-7 days to update a tentative plan as shown in the following table.

The title link
Time and space complexity Github.com/biaochenxuy…
Linear tables (arrays, linked lists, stacks, queues) Github.com/biaochenxuy…
Implementing a front-end route, how to implement browser forward and backward? Github.com/biaochenxuy…
Stack and heap memory, shallow copy and deep copy Github.com/biaochenxuy…
Nonlinear tables (tree, heap) Wonderful to be continued
recursive Wonderful to be continued
Bubble sort Wonderful to be continued
Insertion sort Wonderful to be continued
Selection sort Wonderful to be continued
Merge sort Wonderful to be continued
Quick sort Wonderful to be continued
Count sorting Wonderful to be continued
Radix sort Wonderful to be continued
Bucket sort Wonderful to be continued
Hill sorting Wonderful to be continued
Heap sort Wonderful to be continued
Top 10 classic rankings Wonderful to be continued

If there is any mistake or not precise place, please be sure to give correction, thank you very much.

7. The last

Welcome to Star Github and encourage the author.

Follow my official account and receive the latest wonderful blog posts as soon as possible.

Article can be reproduced, but must indicate the author and source, need to be reproduced to the public number, call me to add the next white list on the line.

Reference article:

JavaScript stack memory and heap memory

JavaScript to achieve shallow copy and deep copy method analysis

Shallow vs. Deep copy (JavaScript)