Understand deep copy and shallow copy in JavaScript

1. The difference between basic types and reference types

1. The difference between basic types and reference types in storage

Now only look at the stack area and the heap area, and assume that they are only local variables.
insert image description here

When the function test() is called:
1. Define the local variable age. Since age is a local variable, apply for memory space in the stack, name it age, and assign a value of 25 to age, which is a basic type, so the value is directly stored in the stack.
2. Define the local variable arr, arr is a local variable, and apply for space in the stack, but because the value assigned to arr is not a basic type, but a reference type (from new), it is necessary to apply for space in the heap to store data 18 , 23, 99, and then assign the address in the heap to arr, so the method stored in arr in the stack is a pointer to the heap area.

2. Basic types and reference types

  • Basic type: It is the value type, that is, the value is stored in the memory area corresponding to the variable, such as: the above age variable memory stores the value 25.
  • Reference type: It is the address type, which stores pointers to the heap. The above arr is a reference type, the address corresponding to arr is stored in the memory, and the real data is stored in the memory area corresponding to the address.

2. Changes in memory of basic types and reference types during assignment

It can be understood that assignment is copying.

1. Basic type

insert image description here

2. Reference type

insert image description here
At this time, if you declare arr1 = arr, after modifying the value of arr[0], the value of arr1[0] will also change.
insert image description here
The memory will change as follows:
insert image description here
arr and arr1 point to the same memory address.

3. Deep copy and shallow copy

The so-called copy is assignment, assigning a variable to another variable is to copy the content of the variable. Assigning the value of one object to another object is to copy the object.

1. There is no problem with the basic type

Because when the basic data type is assigned, the data is assigned (so there is no problem of deep copy and shallow copy).

// 例如:
var x = 100;
var y = x;  // 此时x和y都是100,如果改变y的值,x的值不会改变。

2. There is a problem with the reference type

When assigning a reference type, the assigned value is the address (that is, the content stored in the stack memory by the reference type variable).

// 例如:
var arr = new Array(18, 23, 99);
var arr1 = arr; // 这就是一个简单的浅拷贝

If you change arr1[0] = 33, the value of arr[0] is also 33 (tested above). The reason is that arr and arr1 refer to the same memory area. This is the simplest shallow copy. It just copies the address of arr to arr1, but does not copy the data of arr. The depth of the copy is not enough .

3. Use json object to demonstrate deep copy and shallow copy

(1) Define a json object (the properties of the object are also objects)

var obj = {
    
    
	id: "909",
	name: "小王",
	color: new Array("blue", "pink", "yellow") // 引用类型
}

(2) Copy the obj object

  • (1) Shallow copy
var obj1 = {
    
    };
for(let key in obj) {
    
    
	obj1[key] = obj[key];
}
obj1.color[0] = "green";
console.log(obj);
console.log(obj1);

insert image description here
memory:
original obj object:
insert image description here
shallow copy:
insert image description here

  • (2) Deep copy (preliminary)
var obj = {
    
    
	id: "909",
	name: "小王",
	color: new Array("blue", "pink", "yellow") // 引用类型
}
var obj1 = {
    
    };
for(let key in obj) {
    
    
    if(typeof obj[key] == 'object') {
    
    
        obj1[key] = [];
        for(let i in obj[key]) {
    
    
            obj1[key][i] = obj[key][i];
        }
    } else {
    
    
        obj1[key] = obj[key];
    }
}
obj1.color[1] = "black";
console.log(obj);
console.log(obj1);

insert image description here
Memory:
insert image description here

  • (3) Deep copy (final)

3.1 If the attributes are all json objects, then recursively

var p = {
    
    
    "id": "007",
    "name": "Sean",
    "wife": {
    
    
        "id": "008",
        "name": "Yibo",
        "address": {
    
    
            "city": "beijing",
            "area": "海淀区"
        }
    }
}
function copyDeep(obj) {
    
    
    let newObj = {
    
    };
    for(let key in obj) {
    
    
        if(typeof obj[key] == 'object') {
    
     // 如果是引用类型,就递归
            newObj[key] = copyDeep(obj[key]);
        } else {
    
     // 基本类型,则直接赋值
            newObj[key] = obj[key];
        }
    }
    return newObj;
}
let newP = copyDeep(p);
newP.wife.name = "bobo";
newP.wife.address.city = "shanghai";
console.log(newP);
console.log(p);

insert image description here

3.2 If the attribute is an object that is not a key-value pair such as an array

// 给数组对象增加一个方法,用来复制自己
Array.prototype.copyself = function() {
    
    
    let arr = new Array();
    for(let i in this) {
    
    
        arr[i] = this[i];
    }
    return arr;
}
var aObj = {
    
    
    id: "111",
    name: "Sean",
    like: new Array("apple", "banana", "lemon")
}
function copyObj(obj) {
    
    
    let newObj = {
    
    };
    for(let key in obj) {
    
    
        if(typeof obj[key] == 'object') {
    
    
            newObj[key] = obj[key].copyself();
        } else {
    
    
            newObj[key] = obj[key];
        }
    }
    return newObj;
}
var newVal = copyObj(aObj);
newVal.like[0] = "orange";
console.log(aObj);
console.log(newVal);

insert image description here

Reference link: https://blog.csdn.net/jiang7701037/article/details/98738487

Guess you like

Origin blog.csdn.net/weixin_45832482/article/details/124230663
Recommended