Preface When I went to an interview at a company before, the interviewer asked me a question, saying: "How can I deeply copy an object?" At that time, I felt secretly delighted. Is it necessary to think about such a simple question? So I blurted out: "There are two commonly used methods. The first is to use JSON.parse(JSON.stringify(obj)), and the second is to use for...in plus recursion." After listening to this, the interviewer nodded and was quite satisfied. Ask a questionSo what is the Bug mentioned above? Special object copy First, let's imagine an object that has the following members, without considering common types: const obj = { arr: [111, 222], obj: {key: 'object'}, a: () => {console.log('function')}, date: new Date(), reg: /regular/ig } Then we copy it once using the above two methods respectively JSON Method JSON.parse(JSON.stringify(obj)) Output: It can be seen that both the ordinary objects and arrays in obj can be copied, but the date object becomes a string, the function disappears directly, and the regular expression becomes an empty object. recursion function isObj(obj) { return (typeof obj === 'object' || typeof obj === 'function') && obj !== null } function deepCopy(obj) { let tempObj = Array.isArray(obj) ? [] : {} for(let key in obj) { tempObj[key] = isObj(obj[key]) ? deepCopy(obj[key]) : obj[key] } return tempObj } result: in conclusion From the above test, we can see that these two methods cannot copy objects of function, date, and reg types;
What is a ring? A loop is a circular reference between objects, which results in a closed loop. For example, the following object: var a = {} aa = a Using the above two methods to copy will directly report an error Solution
You can use a WeakMap structure to store objects that have been copied. Each time you copy an object, query the WeakMap to see if the object has been copied. If it has been copied, take out the object and return it. Transform the deepCopy function into the following function deepCopy(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) { cloneObj[key] = isObj(obj[key]) ? deepCopy(obj[key], hash) : obj[key]; } return cloneObj } Copy ring result: Copying of special objects The solution to this problem is rather complicated, because there are too many types of objects that need to be treated specially, so I referred to the structured copy on MDN, and then combined it with the solution to the ring: // Only solve date and reg types, others can be added by yourself function deepCopy(obj, hash = new WeakMap()) { let cloneObj let Constructor = obj.constructor switch(Constructor){ case RegExp: cloneObj = new Constructor(obj) break Case Date: cloneObj = new Constructor(obj.getTime()) break default: if (hash.has(obj)) return hash.get(obj) cloneObj = new Constructor() hash.set(obj, cloneObj) } for (let key in obj) { cloneObj[key] = isObj(obj[key]) ? deepCopy(obj[key], hash) : obj[key]; } return cloneObj } Copy result: For the full version, see lodash deep copy
However, the structured copy on MDN still does not solve the problem of function copying. So far, I have only thought of using the eval method to copy the function, but this method only works for arrow functions. If it is in the form of fun(){}, it will fail. Copy function to add function type Copy result Error type postscriptJavaScript's deep copy has more problems than the ones mentioned above. Another problem is how to copy the properties on the prototype chain? How to copy non-enumerable properties? How to copy Error objects, etc., I will not go into details here. However, it is still recommended to use the JSON method in daily life. This method has covered most of the business needs, so there is no need to complicate simple things. However, if you encounter an interviewer who is nitpicking during the interview, your answer to this question will definitely make him look good. This concludes this article about some pitfalls of JavaScript deep copy. For more relevant JavaScript deep copy content, please search 123WORDPRESS.COM’s previous articles or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future! You may also be interested in:
|
<<: Implementation of crawler Scrapy image created by dockerfile based on alpine
>>: Implementation of tomcat image created with dockerfile based on alpine
This article shares with you the specific method ...
Event Description onactivate: Fired when the objec...
Windows cmd telnet format: telnet ip port case: t...
This article mainly introduces the solution to th...
Installing XML extension in PHP Linux 1. Enter th...
Tomcat defines multiple ClassLoaders internally s...
Preface I just bought a new VPS. The data disk of...
Stored Functions What is a stored function: It en...
1. Introduction Is it considered rehashing old st...
After Vmvare sets the disk size of the virtual ma...
1. Introduction to yum Yum (full name Yellow dogU...
Specific method: Step 1: Stop the mysql service /...
Pitfalls encountered during project deployment Wh...
The most understandable explanation of the accura...
Preface When a 403 cross-origin error occurs No &...