Implementation method of JavaScript deep clone_javascript skills
There is a type of code reuse pattern called "copying properties pattern". When we think of code reuse, we most likely think of code inheritance, but it's important to remember the ultimate goal - we want to reuse code. Inheritance is only a means to achieve code reuse, not the only way. Copying properties is also a reuse pattern, which is different from inheritance. In this pattern, an object will obtain members from another object by simply copying them. Anyone who has used jQuery knows that it has a $.extend() method. In addition to extending third-party plug-ins, it can also be used to copy attributes. Let’s take a look at the implementation code of an extend() function (note that this is not the source code of jQuery, just a simple example):
function extend(parent, child) { var i; //如果不传入第二参数child //那么就创建一个新的对象 child = child || {}; //遍历parent对象的所有属性 //并且过滤原型上的属性 //然后将自身属性复制到child对象上 for(i in parent) { if(parent.hasOwnProperty(i)) { child[i] = parent[i]; } } //返回目标对象child return child; }
The above code is a simple implementation, it only traverses the members of the parent object and copies them to the child object. Let’s test it using the extend() method above:
var dad = {name: "Adam"}; var kid = extend(dad); console.log(kid.name); //Adam
We found that the extend() method can already work normally. But there is a problem. What is given above is a so-called shallow clone. When using shallow copy, if the properties of the child object are changed, and the property happens to be an object, then this operation will also modify the parent object. In many cases, this is not the result we want. Consider the following:
var dad = { counts: [1, 2, 3], reads: {paper: true} }; var kid = extend(dad) //调用extend()方法将dad的属性复制到kid上面 kid.counts.push(4); //把4追加到kid.counts数组里面 console.log(dad.counts); //[1, 2, 3, 4]
Through the above example, we will find that after modifying the kid.counts attribute (adding element 4 to it), dad.counts will also be affected. This is because when using shallow copy, since the object is passed by reference, that is, kid.counts and dad.counts point to the same array (or in memory, they point to the same heap address).
Next, let us modify the extend() function to implement deep copying. What we need to do is to check each attribute of the parent object, and if the attribute happens to be an object, then recursively copy the attributes of the object. In addition, you also need to detect whether the object is an array. This is because the literal creation method of arrays is different from the literal creation method of objects. The former is [] and the latter is {}. To detect an array, you can use the Object.prototype.toString() method. If it is an array, it will return "[object Array]". Let’s take a look at the extend() function of the deep copy version:
function extendDeep(parent, child) { child = child || {}; for(var i in parent) { if(parent.hasOwnProperty(i)) { //检测当前属性是否为对象 if(typeof parent[i] === "object") { //如果当前属性为对象,还要检测它是否为数组 //这是因为数组的字面量表示和对象的字面量表示不同 //前者是[],而后者是{} child[i] = (Object.prototype.toString.call(parent[i]) === "[object Array]") ? [] : {}; //递归调用extend extendDeep(parent[i], child[i]); } else { child[i] = parent[i]; } } } return child; }
Okay, the deep copy function has been written. Let’s test it to see if it can work as expected, that is, whether deep copy can be achieved:
var dad = { counts: [1, 2, 3], reads: {paper: true} }; var kid = extendDeep(dad); //修改kid的counts属性和reads属性 kid.counts.push(4); kid.reads.paper = false; console.log(kid.counts); //[1, 2, 3, 4] console.log(kid.reads.paper); //false console.log(dad.counts); //[1, 2, 3] console.log(dad.reads.paper); //true
Through the above example, we can find that even if the child object's kid.counts and kid.reads are modified, the parent object's dad.counts and kid.reads have not changed, so our purpose has been achieved.
The following is a summary of the basic ideas for implementing deep copy:
1. Check whether the current attribute is an object
2. Because arrays are special objects, it is necessary to detect whether the attribute is an array if it is an object.
3. If it is an array, create an [] empty array, otherwise, create a {} empty object and assign it to the current property of the child object. Then, the extendDeep function is called recursively.
The above example uses a deep copy method implemented by ourselves using a recursive algorithm. In fact, the two methods provided by the new JSON object in ES5 can also achieve deep copying, namely JSON.stringify() and JSON.parse(); the former is used to convert the object into a string, and the latter is used to convert the string Convert to object. Below we use this method to implement a deep copy function:
function extendDeep(parent, child) { var i, proxy; proxy = JSON.stringify(parent); //把parent对象转换成字符串 proxy = JSON.parse(proxy) //把字符串转换成对象,这是parent的一个副本 child = child || {}; for(i in proxy) { if(proxy.hasOwnProperty(i)) { child[i] = proxy[i]; } } proxy = null; //因为proxy是中间对象,可以将它回收掉 return child; }
The following is a test example:
var dad = { counts: [1, 2, 3], reads: {paper: true} }; var kid = extendDeep(dad); //修改kid的counts属性和reads属性 kid.counts.push(4); kid.reads.paper = false; console.log(kid.counts); //[1, 2, 3, 4] console.log(kid.reads.paper); //false console.log(dad.counts); //[1, 2, 3] console.log(dad.reads.paper); //true
The test found that it also achieved deep copying. It is generally recommended to use the latter method, because JSON.parse and JSON.stringify are built-in functions and will be processed faster. In addition, the previous method uses recursive calls. We all know that recursion is a relatively inefficient algorithm.
This is all about the implementation method of JavaScript deep clone. I hope it will be helpful to you!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics











Different JavaScript engines have different effects when parsing and executing JavaScript code, because the implementation principles and optimization strategies of each engine differ. 1. Lexical analysis: convert source code into lexical unit. 2. Grammar analysis: Generate an abstract syntax tree. 3. Optimization and compilation: Generate machine code through the JIT compiler. 4. Execute: Run the machine code. V8 engine optimizes through instant compilation and hidden class, SpiderMonkey uses a type inference system, resulting in different performance performance on the same code.

Python is more suitable for beginners, with a smooth learning curve and concise syntax; JavaScript is suitable for front-end development, with a steep learning curve and flexible syntax. 1. Python syntax is intuitive and suitable for data science and back-end development. 2. JavaScript is flexible and widely used in front-end and server-side programming.

JavaScript is the core language of modern web development and is widely used for its diversity and flexibility. 1) Front-end development: build dynamic web pages and single-page applications through DOM operations and modern frameworks (such as React, Vue.js, Angular). 2) Server-side development: Node.js uses a non-blocking I/O model to handle high concurrency and real-time applications. 3) Mobile and desktop application development: cross-platform development is realized through ReactNative and Electron to improve development efficiency.

This article demonstrates frontend integration with a backend secured by Permit, building a functional EdTech SaaS application using Next.js. The frontend fetches user permissions to control UI visibility and ensures API requests adhere to role-base

I built a functional multi-tenant SaaS application (an EdTech app) with your everyday tech tool and you can do the same. First, what’s a multi-tenant SaaS application? Multi-tenant SaaS applications let you serve multiple customers from a sing

The shift from C/C to JavaScript requires adapting to dynamic typing, garbage collection and asynchronous programming. 1) C/C is a statically typed language that requires manual memory management, while JavaScript is dynamically typed and garbage collection is automatically processed. 2) C/C needs to be compiled into machine code, while JavaScript is an interpreted language. 3) JavaScript introduces concepts such as closures, prototype chains and Promise, which enhances flexibility and asynchronous programming capabilities.

The main uses of JavaScript in web development include client interaction, form verification and asynchronous communication. 1) Dynamic content update and user interaction through DOM operations; 2) Client verification is carried out before the user submits data to improve the user experience; 3) Refreshless communication with the server is achieved through AJAX technology.

JavaScript's application in the real world includes front-end and back-end development. 1) Display front-end applications by building a TODO list application, involving DOM operations and event processing. 2) Build RESTfulAPI through Node.js and Express to demonstrate back-end applications.
