473,322 Members | 1,241 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,322 software developers and data experts.

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.
Dec 6 '05 #1
15 1781
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)

Dec 6 '05 #2
VK

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));

Dec 6 '05 #3
<11**********************@g14g2000cwa.googlegroups .com>
VK <sc**********@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
Dec 6 '05 #4
Christopher Benson-Manica <at***@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.
Dec 6 '05 #5
Christopher Benson-Manica wrote:
Christopher Benson-Manica <at***@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
Dec 6 '05 #6
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.
Dec 6 '05 #7
RobG <rg***@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.
Dec 7 '05 #8
sure!

Dec 7 '05 #9
Christopher Benson-Manica wrote:
RobG <rg***@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
Dec 8 '05 #10
VK wrote:
Christopher Benson-Manica wrote:
Is there a general mechanism to duplicate, or provide for the
duplication of, objects?


3) Also if you don't mind of JSON then you can
var arrayOneCopy = JSON.parse(JSON.stringify(arrayOne));


And since security is not a concern as this data already exists in a
local variable, this would be faster.
var arrayOneCopy = eval(JSON.stringify(arrayOne));

Probably one of the only times I would feel comfortable with eval.

Dec 8 '05 #11
Thomas 'PointedEars' Lahn <Po*********@web.de> wrote:
Your method returns a reference to the calling object; that is not
copying an object, it is retrieving a reference to that object.


That's intentional. If an object's prototype doesn't override the
inherited copy(), it doesn't copy itself. That seems like reasonable
default behavior to me.

--
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.
Dec 8 '05 #12
Christopher Benson-Manica wrote:
Thomas 'PointedEars' Lahn <Po*********@web.de> wrote:
Your method returns a reference to the calling object; that is not
copying an object, it is retrieving a reference to that object.


That's intentional. If an object's prototype doesn't override the
inherited copy(), it doesn't copy itself. That seems like reasonable
default behavior to me.


It does not seem to me, given that Object objects are
extensible, too, without inheriting from another prototype.

My example shows that your approach fails badly on those,
and an approach that fails even with the simplest of objects
can hardly be considered viable for a general solution.
PointedEars
Dec 8 '05 #13
Thomas 'PointedEars' Lahn <Po*********@web.de> wrote:
It does not seem to me, given that Object objects are
extensible, too, without inheriting from another prototype.
I'm not sure I get you here.
and an approach that fails even with the simplest of objects
can hardly be considered viable for a general solution.


Yes, I haven't provided a way for any generic object to be copied.
For my purposes, however, the ability to specify whether objects of
prototype X are copied by reference or value is good enough for a
number of purposes, not least of which is solving the minor problem
that motivated this line of questioning in the first place.

--
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.
Dec 8 '05 #14
Christopher Benson-Manica wrote:
Thomas 'PointedEars' Lahn <Po*********@web.de> wrote:
It does not seem to me, given that Object objects are
extensible, too, without inheriting from another prototype.
I'm not sure I get you here.


var x = {foo: 'bar'};

is defining the reference `x' to a newly created Object object,
that is extended by adding a new property, `foo'. It is the same
as

var x = new Object();
x.foo = 'bar';

That object is extensible and extended here without the use of another
prototype (object). And since all non-host objects are extensible ...
and an approach that fails even with the simplest of objects
can hardly be considered viable for a general solution.


Yes, I haven't provided a way for any generic object to be copied.
For my purposes, however, the ability to specify whether objects of
prototype X are copied by reference or value is good enough for a


"copied by reference or value"? Object references and primitive values
are the only property values you can copy this way. References _are_
values in JS.
number of purposes, not least of which is solving the minor problem
that motivated this line of questioning in the first place.


Fair enough, but you need to be aware, and I am not sure that you already
are, that, consequently, copying properties which values are references to
Object objects (or any user-defined object that does not have a constructor
with a prototype object that defines anything different for that matter),
will not result in copying those objects. It will merely result in copying
the reference to that object, hence modifying the property of such
properties of original object1 will result in modifying the property of
such properties of its "copy" object2:

var object1 = {foo: {bar: 42}};
var object2 = object1.copy();
object2.foo.bar = 23;
alert(object1.foo.bar); // 23, not 42

1. original object
2. object1 --------> original object
3. object1.foo ----> {bar: 42}
4. Create "copy" of object1.
5. _Copy_ property _values_ from object1 to object2.
6. "copy" <-------- object2
7. object1.foo ----> {bar: 42} <------- object2.foo

That goes of course for all objects where only shallow copying of property
values is performed.
PointedEars
Dec 8 '05 #15
Thomas 'PointedEars' Lahn <Po*********@web.de> wrote:
"copied by reference or value"? Object references and primitive values
are the only property values you can copy this way. References _are_
values in JS.
All right, I'll put it another way - the ability to choose whether the
reference I get is to the original object or a new object with the
same properties.
Fair enough, but you need to be aware, and I am not sure that you already
are, that, consequently, copying properties which values are references to
Object objects (or any user-defined object that does not have a constructor
with a prototype object that defines anything different for that matter),
will not result in copying those objects.


Yes, I am aware of that fact, and that is actually the precise
behavior I'm looking for. I do appreciate the heads up all same,
however.

--
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.
Dec 9 '05 #16

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: abu | last post by:
I'm having a problem with Fast Template duplicating the content. Here's the code, hoping someone may be of help, thanks! while(list($last_name)=mysql_fetch_array($data1)) { $data2 =...
5
by: DB_2 | last post by:
I was wondering if there was a way to create a copy of a table in a single SQL statement, together with its column structure and data. In Oracle, there is a "CREATE TABLE new-table AS...
6
by: Robin S. | last post by:
**Eric and Salad - thank you both for the polite kick in the butt. I hope I've done a better job of explaining myself below. I am trying to produce a form to add products to a table (new...
2
by: Todd Plambeck | last post by:
I have an ASP.net order entry system that will occasionally insert duplcate orders into the database. We are using SQL Server for the session state. This also only seems to happen when the server...
2
by: Samuel R. Neff | last post by:
I'm trying to find a good way to handle Control.InvokeRequired without duplicating four lines of code in every function/event. Typically what I've seen in books is this: If InvokeRequired Then...
8
by: Josetta | last post by:
I have found a wealth of information here on how to duplicate records in forms with subforms. I have adapted code found here to work with my forms. It works beautifully the first time I hit the...
0
by: rmli | last post by:
Duplicating a Database using RMAN http://quickdba.blogspot.com/2006/05/duplicating-database-using-rman_22.html
7
by: Brett Romero | last post by:
I need a static version of a class that can be referenced anywhere as a singleton and the same class that can be used as instances. Can this be done without basically creating the same class twice...
3
by: Darren.Ratcliffe | last post by:
Hi everyone I'm using v 2.0 of the framework with C# and am developing a web application. I am finding that my cookie names are duplicating themselves over and over again, for example when I...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.