Deep cloning of objects in JavaScript

Source: Internet
Author: User

0. Greeting

More than one months have not updated the blog, this time back to the school to deal with the matter of the paper, the life of the internship also temporarily over (in the company to work, only to find that the school life is like heaven, I believe that many have graduated from the small partners must be I said, said in the article, please praise, haha! )。 Hope that the next update of their progress can be accelerated, and immediately another year of school recruit, be abused or Daniel abuse others, in short, bless you this year to find a job of the small partners good luck. So, today, talk about a common written test, interview questions, JS object in depth cloning. Turned over this topic, in many places, has been an old problem, but the annual school recruit always test, in fact, think, this topic to examine the knowledge point is quite many, especially the basic knowledge of the examination. Well, gossip doesn't say much, get to the point.

The object in JS

When it comes to the cloning of objects, we must say something about the concept of objects.

The data types in JS are divided into two main categories: primitive type and object type. (1) Primitive types include: Numeric, String, Boolean, null, undefined (the latter two are special primitive values, not detailed here, my previous blog has talked about some) (2) object types include: An object is a collection of properties, Of course there are two special objects----function (a class object in JS), an array (an ordered collection of key values).

Okay, now that the objects are in these two categories, the two types are very different when replicating clones. The original type stores the actual data of the object, and the object type stores the object's reference address (the actual contents of the object are stored separately, in order to reduce the data overhead usually stored in memory). PS: Here, you know, the object's prototype is also a reference object, it puts the methods and properties of the prototype in memory, through the prototype chain to point to the memory address.

Ii. The concept of cloning

Shallow clone: The original type is a value pass, and the object type is still passed as a reference.

Deep cloning: All elements or attributes are completely copied, completely detached from the original object, meaning that all modifications to the new object are not reflected in the original object.

Three, superficial cloning performance

1, Original type

Look at the following section of code:

//representation of numerical cloningvarA= "1";varb=a;b= "2"; Console.log (a);//"1"Console.log (b);//"2"//representation of String clonesvarc= "1";varD=c;d= "2"; Console.log (c);//"1"Console.log (d);//"2"//representation of String clonesvarx=true;vary=X;y=false; Console.log (x);//trueConsole.log (y);//false

As you can see from the code above, the original type can still get the correct result even if we use normal cloning, because the original type stores the actual data of the object.

2. Object type

As I said earlier, functional first class objects, of course, are object types, but the cloning of functions can be achieved by shallow cloning.

var m=function() {alert (1);}; var n=m;n=function() {alert (2);}; Console.log (M ()); // 1console.log (n ()); // 2

As you can see, the function is cloned directly from the normal assignment and does not affect the previous object. The reason is that the cloning of a function creates a separate space in the memory and does not affect each other.

Well, after saying this special "connections", let's talk about the ordinary "players". To facilitate subsequent code performance, I define a complex object type Operson here. Here's a look at the harm of shallow copy of object type:

varoperson={oname:"Rookiebob", Oage:"18", oaddress:{Province:"Beijing"}, ofavorite:["Swimming", {reading:"Book of History"}], Skill:function() {Console.log ("Bob is coding"); }};functionClone (obj) {varresult={};  for(Keyinchobj) {Result[key]=Obj[key]; }    returnresult;}varonew=Clone (Operson); Console.log (oPerson.oAddress.province);//BeijingOnew.oaddress.province= "Shanghai"; Console.log (oPerson.oAddress.province);//Shanghai

Through the above code, you can see, after the object cloning, I modified onew address, found that the original object Operson has also been modified. This indicates that the cloning of the object is not thorough enough, that is to say deep cloning failed!

The realization of deep cloning

In order to ensure that all properties of an object are copied to, we must know that if the resulting element is still an object or array after the For loop, you need to loop again until the element is the original type or function. To get the type of the element, we define a general function that returns the type of the incoming object.

// returns the class of any object passed to him function IsClass (o) {    if(o===nullreturn "null";     if return "Undefined";     return Object.prototype.toString.call (o). Slice (8,-1);}

PS:Object.prototype.toString.call (o) can directly return the class property of an object, such as the string "[object class]", by intercepting class and knowing what type of object is passed in.

Of course there are two questions to explain:

(1) Why not use the ToString method directly? This is to prevent the ToString method in the object from being overridden, in order to properly invoke the ToString () version, the Function.call () method must be called indirectly

(2) Why not use TypeOf to determine the type directly? Because for array, using typeof (Array) returns an object, so the correct array cannot be obtained, and the subsequent cloning of the array will have a fatal problem.

Everything is ready, only owe Cao, the following on the serious start cloning.

//Deep CloningfunctionDeepclone (obj) {varresult,oclass=isclass (obj); //determine the type of result    if(oclass=== "Object") {result={}; }Else if(oclass=== "Array") {result=[]; }Else{        returnobj; }     for(Keyinchobj) {        varcopy=Obj[key]; if(IsClass (copy) = = "Object") {Result[key]=arguments.callee (copy);//Recursive invocation}Else if(IsClass (copy) = = "Array") {Result[key]=Arguments.callee (copy); }Else{Result[key]=Obj[key]; }    }    returnresult;}//returns the class of any object passed to himfunctionIsClass (o) {if(o===NULL)return"Null"; if(o===undefined)return"Undefined"; returnObject.prototype.toString.call (o). Slice (8,-1);}varoperson={oname:"Rookiebob", Oage:"18", oaddress:{Province:"Beijing"}, ofavorite:["Swimming", {reading:"Book of History"}], Skill:function() {Console.log ("Bob is coding"); }};//Deep Clone an objectvaronew=Deepclone (Operson); onew.ofavorite[1].reading= "Picture"; Console.log (onew.ofavorite[1].reading);// PictureConsole.log (operson.ofavorite[1].reading);// history BookoNew.oAddress.province= "Shanghai"; Console.log (oPerson.oAddress.province);//BeijingConsole.log (oNew.oAddress.province);//Shanghai

As you can see from the code above, the deeply cloned object can be completely detached from the original object, and any modifications we make to the new object will not be reflected in the original object, so deep cloning is implemented.

One thing to note here is: why should the result of deepclone this function be judged by type? Here is a situation, if your result is directly {} object, I passed in an array, and after you have copied it, it becomes an object.

//Deep CloningfunctionDeepclone (obj) {varresult={},oclass=isclass (obj); //if (oclass=== "Object") {    //result={};    //}else if (oclass=== "Array") {    //result=[];    //}else{    //return obj;    // }     for(Keyinchobj) {        varcopy=Obj[key]; if(IsClass (copy) = = "Object") {Result[key]=Arguments.callee (copy); }Else if(IsClass (copy) = = "Array") {Result[key]=Arguments.callee (copy); }Else{Result[key]=Obj[key]; }    }    returnresult;}functionIsClass (o) {if(o===NULL)return"Null"; if(o===undefined)return"Undefined"; returnObject.prototype.toString.call (o). Slice (8,-1);}//cloning an arrayvarArr=["A", "B", "C"];varonew=Deepclone (arr); Console.log (onew);//Object {0: "A", 1: "B", 2: "C"}

V. Summary

Said so much, in fact, the key point of deep cloning implementation of the main two: (1) The object type of judgment, using the above IsClass () method, (2) recursive call implementation of all the properties of the object completely copied.

I front-end rookie, I hope this article can inspire everyone, the text is misleading everyone's place, I hope everyone haihan and give correct. If your friends and soft sister feel that the article is helpful to you, your message and recommendation will be a great encouragement to me! Happy Weekend, everyone!

  

Deep cloning of objects in JavaScript

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.