JavaScript-Heap and Stack, Shallow Copy and Deep Copy

What are heap and stack, and how are they related to shallow copy and deep copy?

In the computer field, the stack is two types of data structures, both of which are data structures in which data items are arranged in sequence, and data items can only be inserted and deleted at one end (called the top of the stack).

The main difference between deep copy and shallow copy is that they have different storage types in the memory, while the heap and stack are areas divided into storage in the memory.

The stack is the memory space automatically allocated by the system, which is automatically released by the system; while the heap is dynamically allocated memory, and the size is variable and will not be released automatically.

ECMAScript data types

Therefore, before understanding shallow copy and deep copy, let's first understand the data types in ECMAScript.

basic type

The basic types are:undefined,boolean,number,string,null

The basic type is a simple data segment stored in the stack memory, the data size is determined, the memory space size can be allocated, and it is stored directly by value, so it can be directly accessed.

Reference type

The main reference types are:object,array,function

Reference types are objects stored in heap memory. The actual variable in the stack holds a pointer in memory, the pointer to heap a space. The size of each space is different, and specific allocation should be made according to the situation. When we need to access the value of a reference type, we first obtain the address pointer of the object from the stack , and then obtain the required data from the heap memory.

The main difference between basic types and reference types

The biggest difference between basic types and reference types is actually the difference between passing by value and passing by address .

 

var a = [1,2,3,4,5];
var b = a; //传址
var c = a[0]; //传值
console.log(b); //1,2,3,4,5
console.log(c); //1
b[4] = 6; //改变b数组的某一项值
c = 7; //改变c的值
console.log(a[4]); //6 
console.log(a[0]); //1

From the above we can know that when I change the b array, the a array also changes. But when I change the value of c, a does not change. This is the difference between value passing and address passing .

Because a is an array and belongs to a reference type, when it is assigned to b, it passes the address in the stack (equivalent to creating a new "pointer" with a different name), not an object in the heap memory, so a and b point to The same heap memory. And c is just a data value obtained from a heap memory and stored in the stack. So when b is modified, it will be modified according to the address back to the a heap memory, while c is modified directly on the stack and cannot point to the a heap memory.

 

Shallow copy

From the above content, we can know that when defining an object or array, the variable is often just a heap address. When we use object copy, if the attribute is an object or an array , what we pass at this time is only a heap address. Therefore, when the child object accesses the attribute, it will backtrack to the heap memory pointed to by the parent object according to the address, that is, when the parent and child objects are associated , the attribute values ​​of the two will point to the same memory space.

 

example:

 

var a = {
  key1: 123,
  key2: [1,2]
};
function copy(o){
  var obj = {};
  for(var i in o){
    obj[i] = o[i];
  }
  return obj;
}
var b = copy(a);
b.key1 = 1234; //b对象的key1重新赋值
b.key2.push(3); //b对象的key2数组里面插入一个新的值
console.log(b.key1); //1234
console.log(a.key1): //123
console.log(b.key2); //1,2,3
console.log(a.key2); //1,2,3

In the above code, it can be seen that the value of key1 of b has changed but the value of key1 of a has not changed along with it, but the value of key2 of b has changed after the value of key2 of a has also changed.

This is because the value of key1 belongs to the basic type, so the data segment is passed when copying. But the value of key2 is an object in the heap memory, so when key2 is copied, the address that points to the key2 object is passed. No matter how many key2s are copied, the value is always the memory space of the key2 object that points to a.

Deep copy

Sometimes, we don't want the relationship between parent and child objects , then deep copy can be used at this time. Since the attribute value type is an array and or image, only the address is passed, then we use the following method to solve this problem, and all the attribute types belonging to the object in the parent object can be traversed and assigned to the child object.

 

  • JSON method

    function deepCopy(o){
      return JSON.parse(JSON.stringify(o));
    }
    var a = {
      key: [1,2]
    };
    var b = deepCopy(a); //拷贝a
    b.key.push(3); //往b的key中插入新的值
    console.log(a); //1,2
    console.log(b); //1,2,3
    
  • Use recursion

    function deepCopy(o,c){
      var c = c || {};
      for(var i in o){
        if(typeof o[i] === 'object'){
          c[i] = (o[i].constructor === Array) ? [] : {};
          deepCopy(o[i], c[i]);
        }else{
          c[i] = o[i];
        }
      }
      return c;
    }
    var a = {
      key: [1,2]
    };
    var b = deepCopy(a); //拷贝a
    b.key.push(3); //往b的key中插入新的值
    console.log(a); //1,2
    console.log(b); //1,2,3

 

Guess you like

Origin blog.csdn.net/AN0692/article/details/107997256