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
1. Check whether the existing nginx supports ipv6...
This article uses jQuery to implement the sliding...
1. <div></div> and <span></s...
DIV+css structure Are you learning CSS layout? Sti...
Table of contents What does the COUNT function do...
Table of contents Nginx proxies two socket.io ser...
Call How to call Amap API? The official open docu...
The effect is as follows:Reference Program: <!...
Platform deployment 1. Install JDK step1. Downloa...
Front-end project packaging Find .env.production ...
1. Varnish Overview 1. Introduction to Varnish Va...
The shell script sets access control, and the IP ...
Download url-loader yarn add -D url-loader module...
Sometimes the page is very long and needs an arro...
nginx installation Ensure that the virtual machin...