This is the sixth day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021
background
Learning the front end of three months, ready to brush interview questions, summary summary, a few interview questions a day, to the big factory.
The problem
What is the difference between deep copy and shallow copy? How to implement a deep copy?
Resolution:
The basic type of data
As we all know, there are two main data types in JS:
- Basic types of
- Reference types
The base type data is stored in stack memory and the reference type data is stored in heap memory, and the variable that refers to the data type is an actual reference address that points to heap memory and is stored in the stack.
You can see the picture:
Shallow copy
Shallow copy, it’s important to understand the concept of copy, copy is a clone of a new one. The difference between shallow copy and deep copy is that the copy level is different.
If the attribute is a primitive data type, the copy is the value of the primitive data type; if the reference type is a reference type, the copy is the memory address.
In JS, shallow copies exist:
- Object.assign
- Array.prototype.slice()
.
Array.prototype.concat() - Replication is implemented using ES6 extension operators
Example:
//Object.assign
var obj={name:"qxz".age:45.cc: {c:2}};
var newObj=Object.assign({},obj);
// Extend the operator
var c={a: {c:1.b:2},d: {f:3.e:3}};
varff={... c};Copy the code
Implement a shallow copy yourself:
function clone(obj) {
const newObj = {};
for(let prop in obj) {
if(obj.hasOwnProperty(prop)){ newObj[prop] = obj[prop]; }}return newObj;
}
Copy the code
Deep copy
Deep copy opens up a new stack of two objects with identical properties. Change the value of one object and leave the other unaffected.
Common deep copies:
- _.cloneDeep(value)
- jQuery.extend()
- Json.stringify () has problems with undefined, date,symbol, etc.
- Write a recursive
Example:
//lodash
var objects = [{ 'a': 1 }, { 'b': 2 }];
var deep = _.cloneDeep(objects);
console.log(deep[0] === objects[0]); //false
//JSON.stringify()
const newObj=JSON.parse(JSON.stringify(objects));
Copy the code
Manual recursive implementation of one:
function deepClone(obj, hash = new WeakMap(a)) {
if (obj === null) return obj; // If it is null or undefined, I will not copy it
if (obj instanceof Date) return new Date(obj);
if (obj instanceof RegExp) return new RegExp(obj);
// May be objects or ordinary values if functions do not need deep copies
if (typeofobj ! = ="object") return obj;
// Make a deep copy of an object
if (hash.get(obj)) return hash.get(obj);
let cloneObj = new obj.constructor();
// Find the constructor from the parent class stereotype, which points to the current class itself
hash.set(obj, cloneObj);
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
// Implement a recursive copycloneObj[key] = deepClone(obj[key], hash); }}return cloneObj;
}
Copy the code
Difference, one picture
conclusion
One step at a time, solid work!