Variable type and storage spaceStack memory and heap memoryBasic Data Typesstring, number, null, undefined, boolean, symbol (new in ES6) Variable values are stored in the stack memory, and the values of variables can be directly accessed and modified. Basic data types do not have copies, for example, you cannot modify the value of 1. Reference Types Object Function RegExp Math Date The value is an object, which is stored in the heap memory. The variable in the stack memory stores a pointer to the corresponding address in the heap memory. Graphical storage spacelet a1 = 0; // Stack memory let a2 = "this is string" // Stack memory let a3 = null; // Stack memory let b = { x: 10 }; // Variable b exists in the stack, { x: 10 } exists as an object in the heap let c = [1, 2, 3]; // Variable c exists in the stack, [1, 2, 3] exists as an object in the heap Assignment of reference typeslet a = { x: 10, y: 20 } let b = a; bx = 5; console.log(ax); // 5 Deep copy and shallow copyDeep CopyCopy an object completely from memory, open up a new area in the heap memory to store the new object, and modify the new object will not affect the original object Shallow copyA shallow copy is a bitwise copy of an object, which creates a new object with an exact copy of the original object's property values. If the attribute is a primitive type, the value of the primitive type is copied; if the attribute is a memory address (reference type), the memory address is copied. Assignment of objectsWhen we assign an object to a new variable, what is assigned is actually the address of the object in the stack, not the data in the heap. That is, the two objects point to the same storage space. No matter which object changes, it is actually the content of the storage space that changes. Therefore, the two objects are linked. Comparison of the threeFive common methods of shallow copyObject.assign()The Object.assign() method can copy any number of source object's own enumerable properties to the target object, and then return the target object. But Object.assign() performs a shallow copy Object.assign will traverse all properties of the source object (sources) from left to right, and then assign them to the target object (target) using = var obj = { a: {a: "kobe", b: 39},b:1 }; var initalObj = Object.assign({}, obj); initalObj.aa = "wade"; initalObj.b = 2; console.log(obj.aa); //wade console.log(obj.b); //1 Spread Operatorlet obj = {a:1,b:{c:1}} let obj2 = {...obj}; obj.a=2; console.log(obj); //{a:2,b:{c:1}} console.log(obj2); //{a:1,b:{c:1}} obj.bc = 2; console.log(obj); //{a:2,b:{c:2}} console.log(obj2); //{a:1,b:{c:2}} Array.prototype.sliceThe slice() method returns a new array object that is a shallow copy of the original array determined by begin and end (excluding end). The base type of the original array will not be changed, but the reference type will be changed. let arr = [1, 3, { Username: 'kobe' }]; let arr3 = arr.slice(); arr3[0]=0; arr3[2].username = 'wade' console.log(arr); Array.prototype.concat()let arr = [1, 3, { username: 'kobe' }]; let arr2=arr.concat(); arr3[0]=0; arr2[2].username = 'wade'; console.log(arr); Handwritten shallow copyfunction shallowCopy(src) { var dst = {}; for (var prop in src) { if (src.hasOwnProperty(prop)) { dst[prop] = src[prop]; } } return dst; } Common methods for deep copyjsON.parse(jsON.stringify())There are a few things to note when implementing deep copy via JSON.stringify If the value of the copied object contains a function, undefined, or symbol, the key-value pair will disappear in the JSON string serialized by JSON.stringify(). Unable to copy non-enumerable properties, unable to copy the prototype chain of the object Copying the Date reference type will become a string Copying a RegExp reference type will result in an empty object If the object contains NaN, Infinity, and -Infinity, the serialized result will become null Unable to copy objects in a loop (i.e. obj[key] = obj) let arr = [1, 3, { Username: 'kobe' }]; let arr4 = JSON.parse(JSON.stringify(arr)); arr4[2].username = 'duncan'; console.log(arr, arr4) Handwritten Beggar's Edition Deep CopyFirst of all, this deepClone function cannot copy non-enumerable properties and Symbol types. Here, only the loop iteration is done for the value of Object reference type, and the Array, Date, RegExp, Error, Function reference types cannot be copied correctly. Objects are looped, i.e. circular references (e.g. obj1.a = obj) function clone(target) { if (typeof target === 'object') { let cloneTarget = Array.isArray(target) ? [] : {}; for (const key in target) { cloneTarget[key] = clone(target[key]); } return cloneTarget; } else { return target; } }; Emperor Edition Deep CopyThis example comes from ConardLi's github, source address: https://github.com/ConardLi/ const mapTag = "[object Map]"; const setTag = "[object Set]"; const arrayTag = "[object Array]"; const objectTag = "[object Object]"; const argsTag = "[object Arguments]"; const boolTag = "[object Boolean]"; const dateTag = "[object Date]"; const numberTag = "[object Number]"; const stringTag = "[object String]"; const symbolTag = "[object Symbol]"; const errorTag = "[object Error]"; const regexpTag = "[object RegExp]"; const funcTag = "[object Function]"; const deepTag = [mapTag, setTag, arrayTag, objectTag, argsTag]; function forEach(array, iteratee) { let index = -1; const length = array.length; while (++index < length) { iteratee(array[index], index); } return array; } function isObject(target) { const type = typeof target; return target !== null && (type === "object" || type === "function"); } function getType(target) { return Object.prototype.toString.call(target); } function getInit(target) { const Ctor = target.constructor; return new Ctor(); } function cloneSymbol(target) { return Object(Symbol.prototype.valueOf.call(target)); } function cloneReg(target) { const reFlags = /\w*$/; const result = new targe.constructor(targe.source, reFlags.exec(targe)); result.lastIndex = target.lastIndex; return result; } function cloneFunction(func) { const bodyReg = /(?<={)(.|\n)+(?=})/m; const paramReg = /(?<=\().+(?=\)\s+{)/; const funcString = func.toString(); if (func.prototype) { const param = paramReg.exec(funcString); const body = bodyReg.exec(funcString); if (body) { if (param) { const paramArr = param[0].split(","); return new Function(...paramArr, body[0]); } else { return new Function(body[0]); } } else { return null; } } else { return eval(funcString); } } function cloneOtherType(target, type) { const Ctor = target.constructor; switch (type) { case boolTag: case numberTag: case stringTag: case errorTag: case dateTag: return new Ctor(target); case regexpTag: return cloneReg(target); case symbolTag: return cloneSymbol(target); case funcTag: return cloneFunction(target); default: return null; } } function clone(target, map = new WeakMap()) { // Clone the original type if (!isObject(target)) { return target; } // Initialize const type = getType(target); let cloneTarget; if (deepTag.includes(type)) { cloneTarget = getInit(target, type); } else { return cloneOtherType(target, type); } // Prevent circular reference if (map.get(target)) { return map.get(target); } map.set(target, cloneTarget); // Clone the set if (type === setTag) { target.forEach(value => { cloneTarget.add(clone(value, map)); }); return cloneTarget; } // Clone the map if (type === mapTag) { target.forEach((value, key) => { cloneTarget.set(key, clone(value, map)); }); return cloneTarget; } // Clone objects and arrays const keys = type === arrayTag ? undefined : Object.keys(target); forEach(keys || target, (value, key) => { if (keys) { key = value; } cloneTarget[key] = clone(target[key], map); }); return cloneTarget; } const map = new Map(); map.set("key", "value"); map.set("ConardLi", "code Secret Garden"); const set = new Set(); set.add("ConardLi"); set.add("code secret garden"); const target = { field1: 1, field2: undefined, field3: { child: "child" }, field4: [2, 4, 8], empty: null, map, set, bool: new Boolean(true), num: new Number(2), str: new String(2), symbol: Object(Symbol(1)), date: new Date(), reg: /\d+/, error: new Error(), func1: () => { console.log("code secret garden"); }, func2: function(a, b) { return a + b; } }; const result = clone(target); console.log(target); console.log(result); The above is a detailed explanation of deep copy and shallow copy of JS variable storage. For more information about deep copy and shallow copy of JS variable storage, please pay attention to other related articles on 123WORDPRESS.COM! You may also be interested in:
|
<<: 18 common commands in MySQL command line
>>: Detailed explanation of several ways of communication between Linux user state and kernel state
This article uses examples to explain the concept...
Today we will introduce how to publish the local ...
Table of contents Preface Why does limit deep pag...
1. Why do packaging? Facilitates overall code cal...
The definition and inheritance of classes in JS a...
The rewrite module is the ngx_http_rewrite_module...
1. Achieve results 2. Data format returned by the...
1. Fixed width + adaptive Expected effect: fixed ...
Preface [root@localhost ~]# cat /etc/fstab # # /e...
Table of contents Preface Benefits of axios encap...
<br />According to foreign media reports, in...
Preface We need to retrieve certain data that mee...
Basic syntax You can create a view using the CREA...
Written in front Sometimes you need to install so...
Regarding the high availability solutions for Ora...