Stack in JS
Both heap and stack are an area of data allocated by runtime memory
Heap (heap)
Heap is used to allocate space for complex data types (reference types), such as array objects and object objects. It allocates memory dynamically at runtime, so access is slowCopy the code
The stack (stack)
Stack (stack) mainly stores some basic types of variables and object references, (including pool, pool store constant), its advantage is that the access speed is faster than the heap, and the data in the stack can be shared, but the disadvantage is that the size and life of data in the stack must be determined, lack of flexibilityCopy the code
What are JavaScript data types?
) 1. The value type (basic types: string, number, Boolean, undefined, null (the five kinds of basic types which are accessed by value es6 symbol has been added
2. Reference type: Object(JS except the basic types are all objects, arrays, functions, regular expressions)
Basic data types are stored on the stack
Basic data types are simple segments of data that are stored on the stack. The size of the data is determined, the size of the memory space can be allocated, and they are stored directly by value, so they can be accessed directly by value
let a = 1; let b = a; b = 2; The console. The log (a, b) / / 1, 2Copy the code
Reference data type
Objects stored in heap memory, each space size is different, depending on the specific configuration
Reference type data is actually stored in stack memory as the reference address of the object in heap memory. This reference address is used to quickly locate objects in the saved heap memoryCopy the code
let obj1 = {
name:'lyl'
}
let obj2 = obj1;
obj2.name = "yr";
console.log(obj1.name); // yr
Copy the code
Obj1 and obj2 point to the same heap memory. Obj1 is assigned to obj2, and the heap memory object is actually copied to obj2 at the stack reference address, so both obj1 and obj2 Pointers point to the same heap memory.
Var a = [1, 2, 3, 4]. var b = a; // Address, the data passed from the object to the variable is of reference type and will be stored in the heap; var c = a[0]; // Assign a value to a variable, C is the basic data type, stored in stack memory; Alert (b); change data in stack does not affect data in heap. / / 1, 2, 3, 4 alert (c); //1 // change the value of b[2] = 6; c = 7; alert(a[2]); //6 alert(a[0]); / / 1Copy the code
From the above we can know that when I change the data in B, the data in A also changes; But when I change the value of C, A doesn’t change.
That's the difference between value and address. Because A is an array and a reference, it assigns b an address in the stack (equivalent to creating a pointer with a different name) rather than an object in the heap. C is simply a data value fetched from heap A memory and stored on the stack. So when B makes changes, it will go back to the a heap to make changes according to the address, while C will make changes directly in the stack and cannot point to the MEMORY of a heap.Copy the code
Shallow copy
When we define an object or array, the variable just holds an address. When we use object copy, if the property is an object or array, we just pass an address. Therefore, when the child objects access the property, it will find the heap memory that the parent object points to based on the address.
var a={key1:"1"} function Copy(p){ var c ={}; for (var i in p){ c[i]=p[i] } return c; } a.key2 = ["yr","lyl"] var b = Copy(a); b.key3 = "3" alert(b.key1)//1 alert(b.key3)//3 alert(a.key3); //undefined b.key2.push("xn") alert(a.key2); //yr lyl xnCopy the code
When the modified property becomes an object or array, the parent and child objects are associated
Es6 implements shallow copy
Var a = {name: "yr," eating: [{name: 'the powder of snails'}, {name:' hot and sour powder '}]} var b = Object. The assign ({}, a); //var b = {... a} b.age = 18; B.ating. Push ({name:' cross bridge '}) console.log(a.age, a.ating); //undefined river snail noodles sour and spicy noodles cross bridge rice noodlesCopy the code
The above object.assign and… When copying, the value of the property in the object is an array or object, which are both copied addresses. If the property in the object corresponds to the basic data type, it is copied value
Deep copy
JSON.parse(JSON.stringify(obj))
Json.stringify serialization (object serialization not only stores the data of an object, but also recursively stores the data of every object referenced by the object) uses object serialization to perform “deep cloning” of the object, that is, copying the object itself and the referenced object itself. But you cannot copy the non-enumerable property json.parse to deserialize it
Problems: For example, Date type can be converted to string type, Undefined and RegExp type is lost. Cannot copy an object that has a circular reference. Copy its own enumerable string property, prototype chain lost.
Let obj = {name:'yr', age:undefined, like:[1,2,3,4], reg: New RegExp(), function(){}} object.defineProperty (obj, "sex", {value: "female", Enumerable: false}); let obj1 = JSON.parse(JSON.stringify(obj))Copy the code
If you don’t want the parent object to be associated with the parent object, you can use deep copy. If the property value type is array and/or image, it will only be addressed, so use recursion
function deepCopy(obj) {
let cloneObj = Array.isArray(obj) ? [] : {}
for (let key in obj) {
if(typeof obj[key] === 'object') {
cloneObj[key] = deepCopy(obj[key]);
}else {
cloneObj[key] = obj[key];
}
}
return cloneObj
}
let a = {
age:18,
b: {name:'yr'}
}
let obj = deepCopy(a)
obj.age = 16;
console.log(a,obj)
Copy the code
The closed loop problem
Ring: The child node property assigns the parent node
let a = {
b:{}
}
a.b.c = a;
Copy the code
When the object to be hypercloned is such a closed-loop object, infinite recursion occurs above code addition
a.b.c = a;
Copy the code
A weakMap object is a set of key/value pairs where the keys are weakly referenced. The key must be an object, and the value can be arbitrary.
function deepClone(obj,hash = new WeakMap()){ if(hash.has(obj)) return hash.get(obj) let cloneObj = Array.isArray(obj) ? [] : {} hash.set(obj,cloneObj) for(let key in obj){ if(typeof obj[key] === 'object'){ if(obj[key] === null){ cloneObj[key] = obj[key] }else if(obj[key].constructor === Date){ cloneObj[key] = obj[key] }else if(obj[key].constructor === RegExp){ cloneObj[key] = obj[key] }else{ cloneObj[key] = deepClone(obj[key],hash) } }else{ cloneObj[key] = obj[key] } } return cloneObj } let a = { age:18, b: {name:'yr'}, fn1:function(){ console.log(1) }, c: /a/, w:null, date:new Date(), q:undefined } a.b.c = a; let obj = deepClone(a) obj.age = 16; console.log(a,obj)Copy the code
Deep cloning recommendation tool Lodash
Common tool LoDash
Import lodash from 'lodash' loodash.clonedeep (obj) deep copyCopy the code