Interview questions: Deep copy and shallow copy (+memory map)

Deep copy and shallow copy are mainly for objects whose attributes are objects (reference types)

1. The difference between basic types and reference types 

         1) Basic type: It is a value type, that is, the value is stored in the memory area corresponding to the variable.

         2) Reference type: It is the address type.    

                What is an address: An address is a number. What is the purpose of having an address? It is to make it easy to find. Why should everyone have a unique address at home? That is, your home can be found when mailing. For example: our earliest supermarket bag storage grids, each grid has a number. When you store your bags, the waiter will put your things in a certain grid and give you the number of this grid (a brand). When you finish shopping and pick up your bag, just give the waiter your brand name (with a number), and the waiter will find your bag based on your number. This number is the address of the grid. The same goes for memory. Each memory has a number to facilitate the CPU to find it. Otherwise, in the vast ocean of memory, how can the CPU find data? The above variable arr is a reference type. The memory corresponding to arr stores the address. The real data is in the memory area corresponding to the address. Just like when you fill out your resume, you will write your home address on the resume paper. the address of. The place where you write your home address on your resume is equivalent to arr. Your home can be found based on this address. The place where you write your home address on your resume is equivalent to quoting your home (you can imagine an invisible thread pulling your home. With this invisible thread on your resume, you can find your home by following the clues). That's why it's called a reference type.

 2. Memory changes of basic types and reference types during assignment

        In fact, we can think that assignment is copying.

  •         basic type:

        

  •         Reference type:

        If you assign a value to arr[0], the value of arr1[0] will also change, because arr and arr1 store the same address, and the data they reference is shared.

        If you add a code based on the above: arr[0]=10; then the memory will change as follows:

Three: The difference between basic types and reference types as function parameters

        1. Basic types as parameters of functions 

 

        2. Reference types as parameters of functions: 

 

Four: Deep copy and shallow copy implementation: 

The so-called copy means assignment. Assigning one variable to another variable means copying the contents of the variable. Assigning the value of one object to another object is making a copy of an object.

1. Basic types

Because when assigning values ​​to basic types, data is assigned (so there is no problem of deep copy and shallow copy).

   like: 

   Var x = 100;

   Var y = x; //此时x和y都是100;

   If you want to change the value of y, the value of x will not change.

2. There is a problem with the reference type

        Because when a reference type is assigned a value, the assigned value address (which is the content of the reference type variable stored in the memory) is strongly recommended to read the second point above (changes in memory between basic types and reference types during assignment) several times. To ensure a deep understanding. In this way, once and for all, there will be no problem in the future when encountering any topic related to reference types (such as: during inheritance, the attributes of the parent class are reference types).

      like:

var arr1 = new Array(12,23,34)

Var arr2 = arr1;//这就是一个最简单的浅拷贝

        If you want to change the data referenced by arr2: when arr2[0]=100, then the value of arr1[0] is also 100.

        The reason is that arr1 and arr2 refer to the same memory area (reflected in the second point above).

        This is the simplest shallow copy, because it only copies the address of arr1 to arr2, but does not copy the data of arr1. Therefore, the copy depth is not enough.

3. Use json objects (also reference types) to demonstrate shallow copy and deep copy 

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

var p = {
	"id":"007",
	"name":"刘德华",
	"books":new Array("三国演义","红楼梦","水浒传")//这是引用类型
}

Memory map:

 


  2). Make a copy of the object p

               (1) Shallow copy

var p2 = {};
for(let key in p){
	p2[key] = p[key];	
}
p2.books[0] ="四国";
console.log(p2);
console.log(p);

        The results printed in the console (books[0] of p and p2 have become "Four Kingdoms"): 

 

        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];
	}
}
p2.books[0] ="四国";
console.log(p2);
console.log(p);

        The results printed in the console (only books[0] of p2 became "Four Kingdoms") 

 

        Memory:                


  (3) Deep copy (final) 

         3.1. Deep copy_If the attributes are all json objects, then use recursion

//If the properties of the object are objects (reference types), the properties of the properties are also reference types, that is, there are many nested layers. What to do, we can only recurse

//The following objects need to be copied:

var p = {
	"id":"007",
	"name":"刘德华",
	"wife":{
		"id":"008",
		"name":"刘德的妻子",
		"address":{
			"city":"北京",
			"area":"海淀区"
		}
	}
}
 
//写函数
function copyObj(obj){
	let newObj={};
	for(let key in obj){
		if(typeof obj[key] =='object'){//如:key是wife,引用类型,那就递归
			newObj[key] = copyObj(obj[key])
		}else{//基本类型,直接赋值
			newObj[key] = obj[key];
		}
	}
	return newObj;
}
 
let pNew = copyObj(p);
pNew.wife.name="张三疯";
pNew.wife.address.city = "香港";
console.log(pNew);
console.log(p);

 

 

         3.2. Deep copy_if the attribute is an object of non-key-value pairs such as an array

        You have to deal with it separately: either add a self-replicating function to the array (this is recommended), or judge it separately. 

//给数组对象增加一个方法,用来复制自己
Array.prototype.copyself = function(){
	let arr = new Array();
	for(let i in this){
		arr[i]  = this[i]
	}
	return arr;
}
 
var p = {
	"id":"007",
	"name":"刘德华",
	"books":new Array("三国演义","红楼梦","水浒传")//这是引用类型
}
 
function copyObj(obj){
	let newObj={};
	for(let key in obj){
		if(typeof obj[key] =='object'){//如:key是wife,引用类型,那就递归
			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);  

 

Guess you like

Origin blog.csdn.net/weixin_40381947/article/details/131372951