1. Deep copy/copy and shallow copy/copy methods of js objects/arrays | Add new fields/modify attributes to object arrays | The front end modifies the values from the back end and adds new fields

Deep copy/duplication and shallow copy/duplication methods for js objects

concept:

The difference between deep copy and shallow copy is mainly whether there is a memory area reallocated in the heap for the copied new object.

Shallow copy refers to direct assignment, and only the reference address of the original object is copied, and a piece of memory is still shared in the heap. So when the copy changes, the original object changes too.

arr1=arr2, then arr2 is copied with a reference address, and they share a memory.

Deep copy reallocates a block of memory in the heap for the new object, so operations on the new object will not affect the original object.

Under what circumstances should deep copy be performed?

When we copy an object, we operate on it. In order not to let the new object affect the original object, we need to make a deep copy of it.

Data of reference types such as arrays and objects can be deeply copied.

1. Take the object array as an example - compare the difference between shallow copy and deep copy

Copy an array of arr1 to arr2. And add a new attribute count to arr2.

shallow copy

// 浅度复制
var  arr1=[
			{
    
    id:1,name:'xiaoming',age:16},
			{
    
    id:2,name:"xiaobai",age:19}
		]
var arr2=[]
function copyarr1(arr){
    
    
		for (var i = 0; i < arr.length; i++) {
    
    
			var obj1=arr[i] //obj1直接复制对象名
			obj1["count"]=0 //给arr2的obj添加新属性
			console.log(obj1)
			arr2.push(obj1)
				
		}

	}
copyarr1(arr1)
console.log("--arr2---")
console.log(arr2)

console.log("--arr1---")
console.log(arr1)

insert image description here

Shallow Copy Analysis

It can be seen that the attribute count is added to the arr2 object, and the original arr1 object is also added with attributes.

When arr2 copies arr1, the defined obj1 directly assigns the value assigned by arr1[ i ], at this time, because the sub-object arr1[ i ] of arr is the data obj of the reference type.

Reference data type : the name exists in the stack memory, and the value exists in the heap memory, but the stack memory will provide a reference address pointing to the value in the heap memory.

Therefore, obj1 actually just copied a reference address, and did not copy the value of arr1[i], obj1 and arr1[i] are two pointers, sharing a value.

When we add, delete, or modify obj1, since obj1 and arr1[i] point to the same value, the value shared by them has changed, so the object pointed to by arr1[i] has changed.
shallow copy

In addition, because of the shared value, shallow copy also has some other effects.

Effect of shallow copy when adding new fields to array of objects

Take the shopping cart requirement as an example:

for (var i = 0; i < state.cartlist.length; i++) {
    
    
				if(state.cartlist[i]["id"]==obj["id"]){
    
    
					// 1 判断新添加的数据如果在购物车list中,count++
					state.cartlist[i]["count"]++
					break;
				}
				//2.如果新数据不在购物车,push进数组
				if(i==state.cartlist.length-1){
    
    
					//商品obj加入购物车列表
					state.cartlist.push(obj);
					state.cartlist[i]["count"]++
					break;
				}
			}

For example, click the button to call this function to add a shopping cart. When the new product id=arr[i].id, that is, the shopping cart already has this data. To implement count++, if it is a shallow copy, the first time , when obj1=arr[i], they both share a value in the heap, we name it a, add an attribute count to obj1, and the initial value is 1. This object is pushed into the array.

Then when you click for the second time, when judging the new product id=arr[i].id, the second data is still the value in the called heap, which is the same as the obj that was pushed into the array last time, so count It needs to add 1, but before that, it has to go through the step of adding the attribute count value, that is to say, the count still starts from 1. The number of clicks is increased from 1, which cannot meet the needs of increasing the count by one each time.

2. Implementation method of deep copy of object/array

Object/array deep copy method 1: Create a new object and copy attributes

We redefine an object for obj1 of arr2, let it copy the values ​​inside one by one to form a new object, and then push it into the array arr2. At this time, the pointer of the object in arr2 is no longer the same as arr1[i]. It is an independent new object, the pointer is obj1.

arr1=[
			{
    
    id:1,name:'xiaoming',age:16},
			{
    
    id:2,name:"xiaobai",age:19}
		]
	arr2=[]
	function copyarr1(arr){
    
    
		for (var i = 0; i < arr.length; i++) {
    
    
			var obj1={
    
    }
			obj1["id"]=arr[i]["id"]
			obj1["name"]=arr[i]["name"]
			obj1["age"]=arr[i]["age"]
			obj1["count"]=0
			arr2.push(obj1)
		}
	
	}
copyarr1(arr1)

console.log("--arr2---")
console.log(arr2)

console.log("--arr1---")
console.log(arr1)

Adding attributes to the object of arr2, the value pointed to by arr1 will not change, because the object of arr2 has become a new object independently.
insert image description here

The second method of deep copying of objects/arrays: traversing properties

If there are many attributes in the object, it is obviously not advisable to copy them one by one. Traverse the object and assign values ​​​​in the traversal.

var  arr1=[
			{
    
    id:1,name:'xiaoming',age:16},
			{
    
    id:2,name:"xiaobai",age:19}
		]
	var arr2=[]
	function copyarr1(arr){
    
    
		for (var i = 0; i < arr.length; i++) {
    
    
			var obj1={
    
    }
			for(let key in arr[i]){
    
       //遍历arr[i]对象的属性
			     obj1[key] = arr[i][key]
			 }
			obj1["count"]=0  //给obj1添加新的属性
			arr2.push(obj1)
				
		}

	}
copyarr1(arr1)

console.log("--arr2-遍历的方式-------")
console.log(arr2)

console.log("--arr1---")
console.log(arr1)

insert image description here

Object/array deep copy method three: JSON.parse(JSON.stringify(array))

JSON.parse(JSON.stringify(array)) can implement deep copying of arrays whose data types are not basic variables, which can be understood as two-level deep copying.

That is, the array or object is not a basic type, but also contains an array or object.

The principle is to turn complex arrays into strings and back again. The secondary object inside is successfully copied.

arr=[{
    
    },{
    
    },{
    
    }]
obj={
    
    
	"name":"小白",
	"address":{
    
    
	...
	...
	}
}

Copy method:

arr1=JSON.parse(JSON.stringify(arr))
obj1=JSON.parse(JSON.stringify(obj))

example

when there are objects in the array.

Copy the array directly

var  arr1=[
				{
    
    id:1,name:'xiaoming',age:16},
				{
    
    id:2,name:"xiaobai",age:19}
			]

	var arr2=JSON.parse(JSON.stringify(arr1))
	console.log(arr2)
	console.log("===========1===")
	console.log(arr1)

insert image description here

add attribute

If the objects in the array need to add attributes, then traverse the array, deeply copy each object, and then add attributes.

var  arr1=[
			{
    
    id:1,name:'xiaoming',age:16},
			{
    
    id:2,name:"xiaobai",age:19}
		]
	var arr2=[]
	function func1(arr){
    
    
		for (var i = 0; i < arr.length; i++) {
    
    
			var obj1=JSON.parse(JSON.stringify(arr[i]))  //深度复制
			obj1["count"]=0  //更改arr2的对象属性 添加属性count
			arr2.push(obj1)		
		}

	}
func1(arr1)
console.log("--arr2--JSON方式------")
console.log(arr2)
console.log("--arr1--")
console.log(arr1) 

insert image description here

3. The internal is the deep copy of the array of basic variables

Inside the array are operations on simple data types.

In fact, deep copying is only for arrays or objects with complex types in the array, because this form of [{},{},] cannot copy secondary sub-objects during shallow copying.

Here, the deep copy of the simple data type in the array is to not share the value in the heap, and the two pointers point to the same value. In order to separate out individual pointers and values. separated from the original array. A change in the value of both does not affect the other.

shallow copy

//浅度复制
arr1=[1,2,3]
arr2=arr1

deep copy

1.arr.slice()

arr.slice(start, end), returns an array slice of array from start to end, if there is no parameter, returns an array equal to the length of array.

	  var arr = [1,2,3,4];
	  var copyarr = arr.slice();
	  console.log(copyarr);//[1,2,3,4]

2.arr.concat()

array.concat(array1, array2, ...), is to concatenate array with array1, array2..., if no parameter is passed, it is equivalent to splicing an empty array, that is, returning the same array as itself.

	var arr= [1,2,3];
	var copyarr = arr.concat();

3.arr.copyof()

	  var arr= [1,2,3,4];
	  var copyarr = new int[4];
	  copyarr =arr.copyOf(arr,4);

Guess you like

Origin blog.csdn.net/yangyangdt/article/details/122469035