Deep cloning of JavaScript objects

Source: Internet
Author: User
Tags shallow copy

When you do a project, you need to add a new attribute to the object, and you don't want to modify the original object. So write: var newObj = oldobj, but the object will change after the new object property is changed, because whether it is a new object or an old object, the memory address pointed to is the same, which changes the data in memory.

So the way to find a trickery is to first convert the old object into a string and then convert it to a new object, although it can achieve the effect, but always feel a bit irregular. So I thought of deep cloning.

function Cloneobjectfn (obj) {     //  object copy         return  json.parse ( Json.stringify (obj))}
the object in JSWhen 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 value, String, Boolean, null, undefined(2) The object type includes: The object is a collection of properties, of course, here 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: You know, the prototype of the object 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 cloningShallow 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 performance1, original typelook at the following section of code:
The performance of the numerical cloning var a= "1"; var b=a;b= "2"; Console.log (a);/"1" console.log (b);/"2"
The expression of the string cloning var c= "1"; var d=c;d= "2"; Console.log (c);/"1" console.log (d);/"2"
The performance of string clones is Var x=true;var y=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 TypeThe function-type object, of course, is also the object type, but the cloning of the function 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.  to facilitate subsequent code performance, a complex object type Operson is defined here. Here's a look at the harm of shallow copy of object type:
var operson={    oname: "Rookiebob",    oage: "$",    oaddress:{        province: "Beijing"    },        Ofavorite: [        "Swimming",        {reading: "History book"}    ],    skill:function () {        Console.log ("Bob is Coding");}    }; function Clone (obj) {    var result={};    for (key in obj) {        result[key]=obj[key];    }    return result;} var onew=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, 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 cloningin 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 function IsClass (o) {    if (o===null) return "null" of any object passed to him;    if (o===undefined) 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 a string of "[object number]", by intercepting class and knowing what type of object is passed in. Here the object types do not focus. 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. Here's the real deep clone.
Deep clone function Deepclone (obj) {var result,oclass=isclass (obj);    Determine the type of result if (oclass=== "Object") {result={};    }else if (oclass=== "Array") {result=[];    }else{return obj;        } for (key in obj) {var copy=obj[key];             if (isclass (copy) = = "Object") {Result[key]=arguments.callee (copy);//Recursive call}else if (isclass (copy) = = "Array") {        Result[key]=arguments.callee (copy);        }else{Result[key]=obj[key]; }} return result;    Returns the class function IsClass (o) {if (o===null) return "null" of any object passed to him;    if (o===undefined) return "undefined"; return Object.prototype.toString.call (o). Slice (8,-1);}        var operson={oname: "Rookiebob", Oage: "$", oaddress:{province: "Beijing"}, ofavorite:[    "Swimming", {reading: "History book"}], Skill:function () {Console.log ("Bob is Coding"); }};//depth clones an object var onew=deepclone (Operson); onew.ofavorite[1].reading= "picture"; console.Log (onew.ofavorite[1].reading);//pictureconsole.log (operson.ofavorite[1].reading);//history Book Onew.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, it is clearly passed in an array, the result you copied, and then become an object.
Deep clone function Deepclone (obj) {    var result={},oclass=isclass (obj);    if (oclass=== "Object") {    //     result={};    }else if (oclass=== "Array") {    //     result=[];    }else{    //     return obj;    } for    (key in obj) {        var copy=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];        }    }    return result;} function IsClass (o) {    if (o===null) return "null";    if (o===undefined) return "undefined";    return Object.prototype.toString.call (o). Slice (8,-1);} Clones an array var arr=["A", "B", "C"];var Onew=deepclone (arr); Console.log (onew);//object {0: "A", 1: "B", 2: "C"}

Deep cloning of JavaScript objects

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.