![]() |
Duplicating objects
Is there a general mechanism to duplicate, or provide for the
duplication of, objects? As an example, suppose I need to duplicate an array. I can accomplish this with array.slice( 0 ), but that's not going to cut in general. I could also add a copy method to the Array prototype, like so: Array.prototype.copy=function() { var newArray=[]; for( var idx=0; idx < this.length; idx++ ) { newArray.push( this[idx] ); } return newArray; } and I could write similar copy() methods for various objects. But I feel certain that I'm not the first programmer who has had a need for such functionality. What is the canonical way of doing this? -- Christopher Benson-Manica | I *should* know what I'm talking about - if I ataru(at)cyberspace.org | don't, I need to know. Flames welcome. |
Re: Duplicating objects
Christopher Benson-Manica wrote on 06 dec 2005 in comp.lang.javascript:
> Is there a general mechanism to duplicate, or provide for the > duplication of, objects? As an example, suppose I need to duplicate > an array. I can accomplish this with array.slice( 0 ), but that's not > going to cut in general. I could also add a copy method to the Array > prototype, like so: > > Array.prototype.copy=function() { > var newArray=[]; > for( var idx=0; idx < this.length; idx++ ) { > newArray.push( this[idx] ); > } > return newArray; >} > Array.prototype.copy=function() { return this.concat(); } or simply us an empty .concat() by itself: var b = a.concat() -- Evertjan. The Netherlands. (Replace all crosses with dots in my emailaddress) |
Re: Duplicating objects
Christopher Benson-Manica wrote: > Is there a general mechanism to duplicate, or provide for the > duplication of, objects? As an example, suppose I need to duplicate > an array. I can accomplish this with array.slice( 0 ), but that's not > going to cut in general. I could also add a copy method to the Array > prototype, like so: > > Array.prototype.copy=function() { > var newArray=[]; > for( var idx=0; idx < this.length; idx++ ) { > newArray.push( this[idx] ); > } > return newArray; > } > > and I could write similar copy() methods for various objects. But I > feel certain that I'm not the first programmer who has had a need for > such functionality. What is the canonical way of doing this? There is not such so feel free to propose one ;-) JavaScript object doesn't have clone() method. So in case of array your options are: 1) If array doesn't have other arrays in it (psi-"single-dimention") you use: var arrayOneCopy = arrayOne.slice(0); 2) If array does have other arrays in it (psi-"multi-dimention") you use your code but just make it *recursive* and check for each single element if it's not an array. 3) Also if you don't mind of JSON then you can var arrayOneCopy = JSON.parse(JSON.stringify(arrayOne)); |
Re: Duplicating objects
<1133902815.432020.271870@g14g2000cwa.googlegroups .com>
VK <schools_ring@yahoo.com> wrote: > There is not such so feel free to propose one ;-) Surely someone has already done so? I can't imagine I'm the first person who's wanted duplicated objects... > JavaScript object doesn't have clone() method. Any particular reason for that? > 2) If array does have other arrays in it (psi-"multi-dimention") you > use your code but just make it *recursive* and check for each single > element if it's not an array. Well, as long as I'm proposing things... Object.prototype.copy=function( deep ) { return this; // Use references by default } Array.prototype.copy=function( deep ) { var c=[]; for( var idx=0; idx < this.length; idx++ ) { if( deep ) { c.push( this[idx].copy(true) ); } else { c.push( this[idx] ); } } return c; } -- Christopher Benson-Manica ataru(at)cyberspace.org |
Re: Duplicating objects
Christopher Benson-Manica <ataru@nospam.cyberspace.org> wrote:
> Array.prototype.copy=function( deep ) { > var c=[]; > for( var idx=0; idx < this.length; idx++ ) { > if( deep ) { > c.push( this[idx].copy(true) ); > } > else { > c.push( this[idx] ); > } > } > return c; > } Let me try again: Array.prototype.copy=function( deep ) { if( !deep ) { return this.concat(); } var c=[]; for( var idx=0; idx < this.length; idx++ ) { c.push( this[idx].copy(true) ); } return c; } -- Christopher Benson-Manica | I *should* know what I'm talking about - if I ataru(at)cyberspace.org | don't, I need to know. Flames welcome. |
Re: Duplicating objects
Christopher Benson-Manica wrote:
> Christopher Benson-Manica <ataru@nospam.cyberspace.org> wrote: > > >>Array.prototype.copy=function( deep ) { >> var c=[]; >> for( var idx=0; idx < this.length; idx++ ) { >> if( deep ) { >> c.push( this[idx].copy(true) ); >> } >> else { >> c.push( this[idx] ); >> } >> } >> return c; >>} > > > Let me try again: > > Array.prototype.copy=function( deep ) { > if( !deep ) { > return this.concat(); > } > var c=[]; > for( var idx=0; idx < this.length; idx++ ) { > c.push( this[idx].copy(true) ); > } > return c; > } > That will only work where all the elements of the array are arrays, and it fails when it gets to elements that aren't arrays. Here's my test: var a = [[1,2,3],1,2,3]; var b = a.copy(true); // 'this[idx].copy is not a function' a[0][1] *=5; alert(a[0] + '\n' + b[0]); Here's a copy method based on something I wrote some time ago to copy multi-dimensional arrays: Array.prototype.copy=function() { var A = this; var B = []; for (var i=0, j=A.length; i<j; ++i){ if (typeof A[i] == 'object' && Array == A[i].constructor ){ B[i] = arrayCopy(A[i]); } else { B[i] = A[i]; } } return B; } It is very much slower than concat(), but for small arrays it may be OK. It will also only work on arrays of primitives, it will not work if an element is an object other than an array. You could extend it to handle other types of objects, but that's pretty much what JSON.parse does, so VK's JSON.parse suggestion may be better. <URL:http://www.crockford.com/JSON/js.html> -- Rob |
Re: Duplicating objects
Christopher Benson-Manica wrote:
> Is there a general mechanism to duplicate, or provide > for the duplication of, objects? No. > As an example, suppose I need to duplicate > an array. I can accomplish this with array.slice( 0 ), > but that's not going to cut in general. ... <snip> > and I could write similar copy() methods for various > objects. But I feel certain that I'm not the first > programmer who has had a need for such functionality. You are not but the reason for copying an object has a big influence upon how you would go about it. For example, prototype-based clones can be useful:- var protoCloneObject = (function(){ function constr(){ ; } return (function(obj){ constr.prototype = obj; return new constr(); }); })(); - so that you can create an object as:- var firstObj = new SomeObject(x, y, z); - and then create a new object that has all of the properties and methods of the first object with:- var clone = protoCloneObject(firstObj); - but is still a distinct object instance. With the significant proviso that acting upon the copy will modify the copy but acting upon the first object will also modify all of its copies until those copies have been modified in a way that masks the changes in their prototype. So in some circumstances the result is exactly what you need, and in others it is extremely dubious. > What is the canonical way of doing this? There isn't, and there probably should not be one. Richard. |
Re: Duplicating objects
RobG <rgqld@iinet.net.au> wrote:
> That will only work where all the elements of the array are arrays, and > it fails when it gets to elements that aren't arrays. Well, in my previous post, I had Object.prototype.copy=function() { return this; } which should make it conceptually a no-op except for classes which overrride copy. > It will also only work on arrays of primitives, it will not work if an > element is an object other than an array. You could extend it to handle > other types of objects, but that's pretty much what JSON.parse does, so > VK's JSON.parse suggestion may be better. I will take a look at that in the morning; thanks. -- Christopher Benson-Manica | I *should* know what I'm talking about - if I ataru(at)cyberspace.org | don't, I need to know. Flames welcome. |
Re: Duplicating objects
sure!
|
Re: Duplicating objects
Christopher Benson-Manica wrote:
> RobG <rgqld@iinet.net.au> wrote: >> That will only work where all the elements of the array are arrays, and >> it fails when it gets to elements that aren't arrays. > > Well, in my previous post, I had > > Object.prototype.copy=function() { > return this; > } > > which should make it conceptually a no-op except for classes which > overrride copy. Again: there are _no_ classes in the languages usually discussed here (ECMAScript implementations in a client-side environment); those are OO languages using prototype-based inheritance. Your method returns a reference to the calling object; that is not copying an object, it is retrieving a reference to that object. Given your prototype method above: var x = {foo: 'bar'}; // x.foo == 'bar' var y = x.copy(); // y.foo == 'bar' y.foo = 42; // y.foo == 42 alert(x.foo); // 42 (not 'bar') Graphically, that is: 1. object1 2. x --------> object1 3. x --------> object1 <-------- y What you wanted is: 1. object1 1. x --------> object1 2. object2 3. Copy all properties and property values from object1 to object2. 4. object2 <-------- y PointedEars |
| All times are GMT. The time now is 12:02 AM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.