JavaScript deep copy _javascript tips

Source: Internet
Author: User
Tags extend shallow copy
Let's take a look at the flaws in the superficial copy, how many people do not know?
Copy Code code as follows:

var ooriginal = {
Memnum:1,//number
MEMSTR: "I am A string",//String
Memobj: {
Test1: "Old value"//We LL Test
},
Memarr: [//array
"A string"///String member of array
{//object member of array
Test2: "Try changing Me"//we ' ll test
}
]
};

This is a more complex object that contains objects and arrays. We use prototype's famous inheritance function to complicate it. It is hard to say that it is inherited, jquery is not counted.
Copy Code code as follows:

var extend = function (result, source) {
for (var key in Source)
Result[key] = Source[key];
return result;
}

Test program:
Copy Code code as follows:

var ocopy = Extend ({},ooriginal); Shallow copy
OCopy.memObj.test1 = "New value"; There is a problem, it will reflect to the original object
alert (OORIGINAL.MEMOBJ.TEST1); The copy of the result was modified with the original.
Ocopy.memarr[1].test2 = "I am Changed";
alert (OORIGINAL.MEMARR[1].TEST2); It's the same trick.

<!doctype html> <ptml lang= "en" > <pead> <meta charset= "Utf-8"/> <meta content= "ie=8" http- equiv= "x-ua-compatible"/> <title>javascript deep copy by Masaki </title> <script type= "Text/javascript" > var ooriginal = {memnum:1,//number memstr: "I am A string",//String memobj: {test1: "old value"//We LL Test Memarr: [//array "A string",//String member of array {//object member of array test2: "Try changing Me"//We ' ll Test}]}; var extend = function (result, source) {for (var key in source) Result[key] = Source[key]; return result; var ocopy = Extend ({},ooriginal); Shallow copy oCopy.memObj.test1 = "New value"; There is a problem, it will reflect to the original object on alert (OORIGINAL.MEMOBJ.TEST1); The result copy was modified with the original OCOPY.MEMARR[1].TEST2 = "I am Changed"; alert (OORIGINAL.MEMARR[1].TEST2); Same recruit </script> </pead> <body> <p>javascript deep Copy by Masaki </p> </body> </p Tml>
[Ctrl + A All SELECT Note: If the need to introduce external JS need to refresh to perform]

It seems that if you do not want to modify the original object, we need to specifically deal with the object and array. To deal with them, we have to identify them. Look at the following function:
Copy Code code as follows:

/**
* Type identification-by Masaki:: Cheng (MIT licensed)
* http://www.cnblogs.com/rubylouvre/archive/2010/01/20/1652646.html
*/
The var is = function (Obj,type) {
var toString = object.prototype.tostring,undefined;
return (type = = "Null" && obj = = null) | |
(Type = = "Undefined" && obj = = Undefined) | |
Tostring.call (obj). Slice (8,-1) = = type;
};

The above function is used for type recognition, the typeof is unreliable, the array returns "Object", instanceof does not, it cannot determine the array instance of another document object. Although the use of Object.prototype.toString.call is not perfect, duck type, it is easy to imitate, but always more reliable than before.
The following formal entry to the theme, our deep copy function will specifically handle the value of the object with the array of key-value pairs, for them, the program will create a new object and array for the target object, and then the next layer of handcuffs. We can see that it does not use hasownproperty, in other words, even the properties that can be traversed in the prototype are turned upside down. For an array, we do not need a for (,,,) loop, it can only loop the elements in parentheses, not the other properties attached to the array, so here is still for...in this extra slow method. Because a deep copy detects all the properties, it is possible to create a new object in the middle, so it's a huge, heavy method. Don't use anything if you have nothing.
Copy Code code as follows:

/**
* Type identification-by Masaki:: Cheng (MIT licensed)
* http://www.cnblogs.com/rubylouvre/archive/2010/03/26/1696600.html
*/
Dom.deepcopy = function (result, source) {
for (var key in source) {
var copy = Source[key];
if (result = = copy) continue;//such as Window.window = = window, will fall into a dead loop, need to deal with
if (dom.is (copy, "Object")) {
Result[key] = Arguments.callee (Result[key] | | {}, copy);
}else if (dom.is (copy, "Array")) {
Result[key] = Arguments.callee (Result[key] | | [], copy);
}else{
Result[key] = copy;
}
}
return result;
};

<!doctype html> <ptml lang= "en" > <pead> <meta charset= "Utf-8"/> <meta content= "ie=8" htt p-equiv= "x-ua-compatible"/> <title>javascript deep copy by Masaki </title> <script type= "Text/javascript" > var ooriginal = {memnum:1,//number memstr: "I am A string",//String memobj: {test1: "old value"//We LL Test}, Memarr: [//array "A string",//String member of array {//object member of array test2: "Try changing Me" we ' ll Test}]}; dom = {}; dom.is = function (obj,type) {var toString = object.prototype.tostring,undefined; return (type = = "Null" && obj = = null) | | (Type = = "Undefined" && obj = = Undefined) | | Tostring.call (obj). Slice (8,-1) = = type; }; Dom.deepcopy = function (result, source) {for (var key in source) {var copy = Source[key]; if (result = = copy) continue;//such as Window.window = = window, will fall into a dead loop if (dom.is (copy, "Object")) {Result[key] = Arguments.call EE (Result[key] | | {}, Copy); }else if (dom.is (copy, "Array")) {Result[key] = Arguments.callee (Result[key] | | [], copy); }else{Result[key] = copy; } return result; }; var ocopy = dom.deepcopy ({},ooriginal); Shallow copy oCopy.memObj.test1 = "New value"; There is a problem, it will reflect to the original object on alert (OORIGINAL.MEMOBJ.TEST1); The result copy was modified with the original OCOPY.MEMARR[1].TEST2 = "I am Changed"; alert (OORIGINAL.MEMARR[1].TEST2); Same recruit </script> </pead> <body> <p>javascript deep Copy by Masaki </p> </body> </p Tml>
[Ctrl + A All SELECT Note: If the need to introduce external JS need to refresh to perform]

Author: Masaki
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.