Deep and shallow copies are often used in interviews to gauge your understanding of basic types and reference types. In my countless interviews, no candidate has been able to answer this question, including many training teachers from institutions. This article will help you understand the difference between primitive types and reference types. If you understand the difference, you should not be afraid of any programming language, because this is not JS. It is the knowledge of any programming language.
Deep and shallow copies are mainly for objects whose properties are objects (reference types)
Basic types and reference types
1. Learn about memory first
Memory partitions are almost the same in any programming language
Memory is used to store data. Data of different types is stored in different areas, that is, classified storage. Different areas have different functions and functions. Just like your closet at home, there are different areas: a suit area, socks area, etc. I’m sure everyone keeps these two things in different areas. Otherwise, when you are dressed in a suit to attend a high-end banquet, hand stuffed in the pocket, out of a smelly sock, is not very embarrassing!! Haha!!
The following is a partition diagram of memory. Memory is divided into four areas: stack area (stack), heap area, global static area, read-only area (constant area and code area).
https://blog.csdn.net/jiang7701037/article/details/98728249
2. The difference between the memory storage of primitive and reference types
For now, we’re just looking at the stack and heap, and we’re assuming that the rest of the stack is local.
When testf is called,
1) Define the local variable age, since age is a local variable, so allocate memory space in the stack, call it age, and since the value 250 assigned to age is a basic type, so, the value is directly stored in the stack.
2) Define the local variable arr, because arR is a local variable, so the space in the stack, but what is stored in arR memory? Since the value assigned to arr is not a basic type, but a reference type (new), we first request space in the heap for data 12,23,34, and so on. Assign the address of the heap area to ARR.
What exactly are primitive types and reference types
1) Basic type: is the value type, that is, in the corresponding memory area of the variable is stored value, for example: above the age variable corresponding memory store value 250.
2) Reference type: address type.
What is an address: An address is a number, what is the use of an address, is easy to find. Why everyone should have a unique address at home is to be able to find your home when mailing.
For example, in our earliest supermarket, each box had a number. When you deposit your bag, the waiter would put your things in a certain box and give you the number of this box (a brand). When you pick up your bag after shopping, give your tag (numbered) to the waiter directly, and the waiter will find your bag according to your number. This number is the address of the grid. Memory is the same, each memory has a number, easy for the CPU to find. Otherwise, the vast ocean of memory, CPU to find data by what to find.
The arR variable above is the reference type, the arR corresponds to the memory where the address is stored, the real data is in the memory corresponding to the address, just like when you fill out your resume, you write your home address on the resume piece of paper. Your home address on your resume is the equivalent of an ARR. And your home is based on this address. Putting your home address on your resume is like referencing your home (imagine an invisible thread pulling your home, and following the invisible thread through your resume will lead you to your home). That’s why they’re called reference types.
Memory changes during assignment of base and reference types
You can think of assignment as copying.
1. Basic Types:
2. Reference type:
If arr[0] is assigned, the value of arr1[0] will also change, because arr and ARR1 hold the same address, which means that the two references are shared. Just as you write your home address in many places (the piece of paper in your resume, the piece of paper in your household registration book). So many pieces of paper referencing your home. Find your home according to one piece of paper, put one million in cash to your home (data changed, equivalent to ARR [0]=10), then find your home according to the address of another piece of paper, you find that you are one million in (don’t tell me that someone took it).
If you add a line of code to the above: arr[0]=10; Then memory will have the following changes:
The difference between primitive types and reference types as function parameters
1. Primitive types as arguments to functions
2, reference type as argument to function:
Deep copy and shallow copy:
Finally deep copy and shallow copy.
In fact, I mentioned copying in the second point, and by copying, I mean assignment. To assign one variable to another is to copy the contents of the variable. To assign the value of one object to another is to make a copy of an object.
1. There is no problem with basic classes.
This is because when primitive types are assigned, they are assigned to data (so there is no problem with deep and shallow copies).
Such as:
Var x = 100;
Var y = x; // both x and y are 100;
If you change the value of y, the value of x doesn’t change.
2. There are problems with reference types
When a reference type is assigned, the address of the assigned value (that is, the contents of the reference type variable stored in memory) is strongly recommended to look at the second point (the change in memory during the assignment of the base type and reference type) several times to ensure that you understand it well. This way, once and for all, you’ll have no problem later on in any topic related to reference types (e.g., when inheriting, the parent class’s attribute is a reference type).
Such as:
Var arr1 = new Array(12,23,34)
Var arr2 = arr1; // This is the simplest shallow copy
If you want to change the data referenced by ARR2: arR2 [0]=100, then arr1[0] is also 100.
The reason is that ARR1 and ARR2 refer to the same memory region (as shown in the second point above).
This is the simplest shallow copy, because it gives ARR2 a copy of the address, not the data of ARR1. So, the depth of the copy is not enough
3. Use JSON objects (reference types) to demonstrate shallow and deep copies
1) Define a JSON object (its properties are also objects)
Var p = {" id ":" 007 ", "name" : "Andy lau", "books" : the new Array (" the romance of The Three Kingdoms ", "a dream of red mansions", "water margin") / / this is a reference type}Copy the code
Memory:
2) Make a copy of the object P
- (a) shallow copy
var p2 = {}; for( let key in p){ p2[key] = p[key]; } p2.books[0] = "; console.log(p2); console.log(p);Copy the code
The result printed in the console (both P and P2’s books[0] become “Shikoku”) :
Memory:
- (2) Deep copy (preliminary)
var p2 = {}; for( let key in p){ if( typeof p[key]== 'object'){ p2[key]=[]; For (let I in p[key]){p2[key][I] = p[key][I]} else{p2[key] = p[key]; for(let I in p[key]){p2[key][I] = p[key][I]} else{p2[key] = p[key]; }} p2.books[0] = "; console.log(p2); console.log(p);Copy the code
Results printed in the console (only P2’s books[0] became “Shikoku”)
Memory:
(3) Deep copy (final)
If the attributes are JSON objects, use recursion
// If the attribute of an object is an object (reference type), the attribute’s attribute is also a reference type, i.e., many layers are nested. What do you do, just recurse
// Copy the following objects:
Var p = {" id ":" 007 ", "name" : "Andy lau", "the wife" : {" id ":" 008 ", "name" : "pfund wife", "address" : {" city ":" Beijing ", "area" : Function copyObj(obj){let newObj={}; For (let key in obj){if(typeof obj[key] == 'object'){newObj[key] = copyObj(obj[key])} else{if(typeof obj[key] == 'object'){newObj[key] = copyObj(obj[key])} else{ NewObj [key] = obj[key]; } } return newObj; } let pNew = copyObj(p); Pnew.tue. name= "pnew.tue. name "; Pnew.tume.address. city = "Hong Kong "; console.log(pNew); console.log(p);Copy the code
3.2. Deep copy _ If the property is an object that is not a key-value pair such as an array
You have to do it separately: either add a self-replicating function to the array (recommended), or decide separately.
Array.prototype.copyself = function(){let arr = new Array(); array.prototype.copySelf = function(){let arr = new Array(); for( let i in this){ arr[i] = this[i] } return arr; } var p = {"id": "007", "name": "Andy ", "books": New Array(" The Three Kingdoms ", "The Dream of the Red Chamber "," the Water margin ")} 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 pNew = copyObj(p); PNew. Books [0] = "中 国"; console.log(pNew); console.log(p);Copy the code
This article unexpectedly wrote a morning, dear, please read with gratitude heart
The original [link] (blog.csdn.net/jiang770103…).