当前位置:网站首页>Deep copy and shallow copy in JS

Deep copy and shallow copy in JS

2022-07-23 06:25:00 Senora

js Deep copy shallow copy in

  • Understand deep copy shallow copy
  • Deep copy and shallow copy in code
  • Implementation method of copy

One 、 Understand deep copy shallow copy

1.1 Deep copy ( Value copy )

Will create an identical object , Old and new objects do not share memory , Modify the new object Can't Influence the original object .

1.2 Shallow copy ( Reference copy )

Copy only pointers to an object , Do not copy the object itself , New and old objects still share the same block of memory . Modify the new object Meeting Influence the original object .

1.3 difference

Copying Basic data type In fact, there is no distinction between deep copy and shallow copy , Because they copy the values of the original data type .
When copying is Reference data type When , Differentiate between shallow copies 、 Deep copy , Because shallow copy only copies the first level attributes of the reference data type , Deep copy can recursively copy attributes of reference data types .

Two 、 Deep copy and shallow copy in code

js Data types in :

  • Basic data type : character string (string)、 The number (number)、 Boolean value (boolean)、undefined、null ;
  • Reference data type : object (Object)、 Array (Array)、 function (Function);

Yes Basic data type replicate , And reassign , It doesn't affect the original variable , This is it. Deep copy .

let myname = ' Dahua ';
let age = myname;
age = 22;
console.log(myname); // Dahua 
console.log(age); //22

myname This variable will open up an address in memory , Store a value of Dahua ,age This variable copies myname So they all point to the same address , It also points to the same value , But yes age When reassigning , Will open up an address in memory to store another value 22.

Yes Reference data type replicate , And reassign , Will affect the original variables , This is it. Shallow copy .

let obj1 = {
    
    myname: " Dahua ",
    age: 12
}
let obj2 = obj1;
obj2.age = 22;

// Inside age All become 22
console.log(obj1); 
console.log(obj2);

For reference data types , And then there is Pile up and Stack That's what I'm saying ,obj1 Will open up a memory address , Corresponding to value ( This is the stack ), But the value of this memory address will be assigned to another address , The corresponding value is created in another address ( It's a pile ),obj2 When copying , You'll find the heap all the way through the stack to copy , Once modified , that obj1 and obj2 Will be affected , Because they all point to the same address .

3、 ... and 、 Implementation method of copy

In the actual project development process , In most cases, you don't want to make shallow copies of objects , Because values affect each other , It's easy to make mistakes , You can convert a shallow copy into a deep copy .

3.1 The implementation of deep copy

1、JSON.stringify()

JSON.parse(JSON.stringify(obj)) It is one of the most commonly used deep copy methods , Its principle is to make use of JSON.stringify take js Object serialization (JSON character string ), Reuse JSON.parse To deserialize ( Restore ) js object .

This method can simply and rudely implement deep copy , But there are still problems , If there is a function in the copied object ,undefined,symbol, When used JSON.stringify() After processing , Will disappear .

let obj1 = {
      a: 0,b: {
    c: 0}};
let obj2 = JSON.parse(JSON.stringify(obj1));
obj1.a = 1;
obj1.b.c = 1;
console.log(obj1); // {a: 1, b: {c: 1}}
console.log(obj2); // {a: 0, b: {c: 0}}

2、 function library lodash Of _.cloneDeep Method

The library also provides _.cloneDeep Used to do Deep Copy

var _ = require('lodash');
var obj1 = {
    
    a: 1,
    b: {
     f: {
     g: 1 } },
    c: [1, 2, 3]
};
var obj2 = _.cloneDeep(obj1);
console.log(obj1.b.f === obj2.b.f);// false

3、 Extension operator
Using the extension operator, the first level copy of an object or array can be Deep copy .

let obj1 = {
    a:1,b:{
    c:1}}
let obj2 = {
    ...obj1};
obj1.a = 2;
console.log(obj1); //{a:2,b:{c:1}}
console.log(obj2); //{a:1,b:{c:1}}
obj1.b.c = 2;
console.log(obj1); //{a:2,b:{c:2}}
console.log(obj2); //{a:1,b:{c:2}}

4、 Implement deep copy function ( Solve circular references )

//  The implementation of deep copy 
function deepCopy(obj, map) {
    
	// Determine whether it is the first time to call deepCopy Method , If yes, create one weakmap Instance to load the objects that appear in the traversal process 
	if(!map){
    
		map = new WeakMap()
	}
	// Judge the incoming obj Is it an object 
	if( obj === null || typeof obj !== 'Object' ){
    
    	return obj
	}
	// If map The existence of this object in indicates that there is a circular reference problem 
	if(map.get(obj)){
    
  		return obj
  	}
	//map If not, go map Save the object in 
	map.set(obj,obj)
	// according to obj The type of newObj Create initial values 
	let newObj = Array.isArray(obj) ? [] : {
    }
	// Traverse obj
	for(let i in obj){
    
		if(obj.hasOwnproperty(i)){
     // Judge whether the current attribute is obj Properties of itself 
			if(typeof obj[i] === 'Object'){
     // Judge whether the current attribute is of object type 
		    	newObj[i] = deepCopy(obj[i],map) // If it is an object type, use this method for recursive processing 
			}else{
    
				newObj[i] = obj[i] // Copy directly instead of object type 
			}
		}
	}
	return newObj // Return the copy completed newObj
}

3.2 Implementation method of shallow copy

1、Object.assign()
Object.assign() yes ES6 Copy method of object in , The first parameter accepted is the target object , The remaining parameters are the source object , usage :Object.assign(target, source_1, ···), This method can realize shallow copy , It can also realize deep copy of one-dimensional objects .

This method needs to pay attention to :

  • If the target object and the source object have the same name attribute , Or more than one source object has the same name , Then the following properties will overwrite the previous properties .
  • If the function has only one parameter , When the parameter is an object , Return the object directly ; When the parameter is not an object , It will first convert the parameter to an object and then return .
  • because null and undefined Can't be converted to objects , So the first parameter cannot be null or undefined, Will report a mistake .
let target = {
    a: 1};
let object2 = {
    b: 2};
let object3 = {
    c: 3};
Object.assign(target,object2,object3);  
console.log(target);  // {a: 1, b: 2, c: 3}

2、 Extension operator
Using the extension operator, you can start copying objects or arrays at the second level Shallow copy .

let obj1 = {
    a:1,b:{
    c:1}}
let obj2 = {
    ...obj1};
obj1.a = 2;
console.log(obj1); //{a:2,b:{c:1}}
console.log(obj2); //{a:1,b:{c:1}}
obj1.b.c = 2;
console.log(obj1); //{a:2,b:{c:2}}
console.log(obj2); //{a:1,b:{c:2}}

3、 Array method to realize shallow copy of array

(1)Array.prototype.slice

slice() The method is JavaScript A method of array , This method returns the selected element from an existing array : usage :array.slice(start, end), This method does not change the original array .
This method has two parameters , Both parameters are optional , If neither parameter is written , You can implement an array Shallow copy .

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

(2)Array.prototype.concat

concat() Method is used to merge two or more arrays . This method does not change the existing array , Instead, it returns a new array . This method has two parameters , Both parameters are optional , If neither parameter is written , You can implement an array Shallow copy .

let arr = [1,2,3,4];
console.log(arr.concat()); // [1,2,3,4]
console.log(arr.concat() === arr); //false

4、 Implement shallow copy function

//  Shallow copy implementation ;
function shallowCopy(object) {
    
	//  Copy objects only 
	if (!object || typeof object !== "object") return;
	//  according to  object  Whether to create an array or an object 
	let newObject = Array.isArray(object) ? [] : {
    };
	//  Traverse  object, And the judgment is  object  It's the property of 
	for (let key in object) {
    
		if (object.hasOwnProperty(key)) {
    
			newObject[key] = object[key];
		}
	}
	return newObject;
}

More links * Convert shallow copy to deep copy ,Vue Shallow copy and deep copy in

原网站

版权声明
本文为[Senora]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/204/202207221805084948.html