Copy an Object?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Harag

    Copy an Object?

    Hi all

    If I create an object with the following:

    var ob1 = new objMyDefinedObj ect();

    then I assign it to a new variable.

    var ob2 = ob1

    I know that this isn't coping the object into a new variable, its just
    another reference to the SAME object unlike

    var a = 20;
    var b= a;

    Which creates a copy of the variable "a" and stores it in variable
    "b".

    How can I copy my above object into a new variable rather than
    reference the same object ? What I want to do is create the object, do
    a load of property changes, then copy the object into a new variable
    and do a load more property changes.

    Thanks.

    Al.
  • Harag

    #2
    Re: Copy an Object?

    On Tue, 03 Aug 2004 09:11:50 +0100, Harag
    <haragREMOVECAP S@softhome.com> wrote:
    [color=blue]
    >Hi all
    >
    >If I create an object with the following:
    >
    >var ob1 = new objMyDefinedObj ect();
    >
    >then I assign it to a new variable.
    >
    >var ob2 = ob1
    >
    >I know that this isn't coping the object into a new variable, its just
    >another reference to the SAME object unlike
    >
    >var a = 20;
    >var b= a;
    >
    >Which creates a copy of the variable "a" and stores it in variable
    >"b".
    >
    >How can I copy my above object into a new variable rather than
    >reference the same object ? What I want to do is create the object, do
    >a load of property changes, then copy the object into a new variable
    >and do a load more property changes.
    >
    >Thanks.
    >
    >Al.[/color]


    NVM, I've found a solution... not sure if its the perfect way, so if
    anyone has a better way then please advise.

    Code pasted below for anyone interested.

    Thanks.

    Al

    THE CODE:
    --------------------

    <script type="text/javascript">
    // Q879 How can I clone or make a copy of an object, rather than
    // just make a copy of the objects reference, even when the object
    // contains other objects?
    //
    // Source: http://developer.irt.org/script/object.htm
    // Source: http://developer.irt.org/script/879.htm
    // A couple of modificates by me to add the "method" for displaying
    // objects rather than a standalone function.

    function bookObject(titl e,author,publis her,isbn,editio n) {
    this.title = title;
    this.author = author;
    this.publisher = publisher;
    this.isbn = isbn;
    this.edition = edition;
    }

    function authorObject(fi rstname, surname) {
    this.firstname = firstname;
    this.surname = surname;
    this.name = firstname + ' ' + surname;
    }


    function _displayObjectP ropertiesAndMet hods() {
    var output = '';
    for (i in this){
    if (typeof this[i] == 'object') {
    output += this[i].display();
    }
    if (typeof this[i] == 'string') {
    output += i + ' = ' + this[i] + '\n';
    }
    }
    return output;
    }

    bookObject.prot otype.display = _displayObjectP ropertiesAndMet hods;
    authorObject.pr ototype.display = _displayObjectP ropertiesAndMet hods;

    function cloneObject(wha tObject) {
    for (i in whatObject) {
    if (typeof whatObject[i] == 'object') {
    this[i] = new cloneObject(wha tObject[i]);
    }
    else
    this[i] = whatObject[i];
    }
    }

    // Example code on how to clone....

    var author1 = new authorObject('D avid','Flanagan ')

    var book1 = new bookObject('Jav aScript The Definitive
    Guide',author1, "O'Reilly", '1-56592-234-4','2nd Edition');

    var book2 = new cloneObject(boo k1);

    book2.edition = '3rd Edition';
    book2.isbn = '1-56592-392-8';

    var book3 = new cloneObject(boo k2);

    book3.edition = '4rd Edition';
    book3.isbn = '0-596-00048-0';

    alert(book1.dis play());
    alert(book2.dis play());
    alert(book3.dis play());

    </script>



    Comment

    • Fox

      #3
      Re: Copy an Object?



      Harag wrote:[color=blue]
      >
      > On Tue, 03 Aug 2004 09:11:50 +0100, Harag
      > <haragREMOVECAP S@softhome.com> wrote:
      >[color=green]
      > >Hi all
      > >
      > >If I create an object with the following:
      > >
      > >var ob1 = new objMyDefinedObj ect();
      > >
      > >then I assign it to a new variable.
      > >
      > >var ob2 = ob1
      > >
      > >I know that this isn't coping the object into a new variable, its just
      > >another reference to the SAME object unlike
      > >
      > >var a = 20;
      > >var b= a;
      > >
      > >Which creates a copy of the variable "a" and stores it in variable
      > >"b".
      > >
      > >How can I copy my above object into a new variable rather than
      > >reference the same object ? What I want to do is create the object, do
      > >a load of property changes, then copy the object into a new variable
      > >and do a load more property changes.
      > >
      > >Thanks.
      > >
      > >Al.[/color]
      >
      > NVM, I've found a solution... not sure if its the perfect way, so if
      > anyone has a better way then please advise.
      >
      > Code pasted below for anyone interested.
      >
      > Thanks.
      >
      > Al
      >
      > THE CODE:
      > --------------------
      >
      > <script type="text/javascript">
      > // Q879 How can I clone or make a copy of an object, rather than
      > // just make a copy of the objects reference, even when the object
      > // contains other objects?
      > //
      > // Source: http://developer.irt.org/script/object.htm
      > // Source: http://developer.irt.org/script/879.htm
      > // A couple of modificates by me to add the "method" for displaying
      > // objects rather than a standalone function.
      >
      > function bookObject(titl e,author,publis her,isbn,editio n) {
      > this.title = title;
      > this.author = author;
      > this.publisher = publisher;
      > this.isbn = isbn;
      > this.edition = edition;
      > }
      >
      > function authorObject(fi rstname, surname) {
      > this.firstname = firstname;
      > this.surname = surname;
      > this.name = firstname + ' ' + surname;
      > }
      >
      > function _displayObjectP ropertiesAndMet hods() {
      > var output = '';
      > for (i in this){
      > if (typeof this[i] == 'object') {
      > output += this[i].display();
      > }
      > if (typeof this[i] == 'string') {
      > output += i + ' = ' + this[i] + '\n';
      > }
      > }
      > return output;
      > }
      >
      > bookObject.prot otype.display = _displayObjectP ropertiesAndMet hods;
      > authorObject.pr ototype.display = _displayObjectP ropertiesAndMet hods;
      >
      > function cloneObject(wha tObject) {
      > for (i in whatObject) {
      > if (typeof whatObject[i] == 'object') {
      > this[i] = new cloneObject(wha tObject[i]);
      > }
      > else
      > this[i] = whatObject[i];
      > }
      > }
      >
      > // Example code on how to clone....
      >
      > var author1 = new authorObject('D avid','Flanagan ')
      >
      > var book1 = new bookObject('Jav aScript The Definitive
      > Guide',author1, "O'Reilly", '1-56592-234-4','2nd Edition');
      >
      > var book2 = new cloneObject(boo k1);
      >
      > book2.edition = '3rd Edition';
      > book2.isbn = '1-56592-392-8';
      >
      > var book3 = new cloneObject(boo k2);
      >
      > book3.edition = '4rd Edition';
      > book3.isbn = '0-596-00048-0';
      >
      > alert(book1.dis play());
      > alert(book2.dis play());
      > alert(book3.dis play());
      >
      > </script>[/color]

      or:

      Object.prototyp e.clone = function() { return this.valueOf(); }

      //seems to work okay

      Comment

      • Harag

        #4
        Re: Copy an Object?

        On Tue, 03 Aug 2004 05:53:28 -0500, Fox <fox@fxmahoney. com> wrote:
        [color=blue]
        >
        >
        >Harag wrote:[color=green]
        >>
        >> On Tue, 03 Aug 2004 09:11:50 +0100, Harag
        >> <haragREMOVECAP S@softhome.com> wrote:
        >>[color=darkred]
        >> >Hi all
        >> >
        >> >If I create an object with the following:
        >> >
        >> >var ob1 = new objMyDefinedObj ect();
        >> >
        >> >then I assign it to a new variable.
        >> >
        >> >var ob2 = ob1
        >> >
        >> >I know that this isn't coping the object into a new variable, its just
        >> >another reference to the SAME object unlike
        >> >
        >> >var a = 20;
        >> >var b= a;
        >> >
        >> >Which creates a copy of the variable "a" and stores it in variable
        >> >"b".
        >> >
        >> >How can I copy my above object into a new variable rather than
        >> >reference the same object ? What I want to do is create the object, do
        >> >a load of property changes, then copy the object into a new variable
        >> >and do a load more property changes.
        >> >
        >> >Thanks.
        >> >
        >> >Al.[/color]
        >>
        >> NVM, I've found a solution... not sure if its the perfect way, so if
        >> anyone has a better way then please advise.
        >>
        >> Code pasted below for anyone interested.
        >>
        >> Thanks.
        >>
        >> Al
        >>
        >> THE CODE:
        >> --------------------
        >>
        >> <script type="text/javascript">
        >> // Q879 How can I clone or make a copy of an object, rather than
        >> // just make a copy of the objects reference, even when the object
        >> // contains other objects?
        >> //
        >> // Source: http://developer.irt.org/script/object.htm
        >> // Source: http://developer.irt.org/script/879.htm
        >> // A couple of modificates by me to add the "method" for displaying
        >> // objects rather than a standalone function.
        >>
        >> function bookObject(titl e,author,publis her,isbn,editio n) {
        >> this.title = title;
        >> this.author = author;
        >> this.publisher = publisher;
        >> this.isbn = isbn;
        >> this.edition = edition;
        >> }
        >>
        >> function authorObject(fi rstname, surname) {
        >> this.firstname = firstname;
        >> this.surname = surname;
        >> this.name = firstname + ' ' + surname;
        >> }
        >>
        >> function _displayObjectP ropertiesAndMet hods() {
        >> var output = '';
        >> for (i in this){
        >> if (typeof this[i] == 'object') {
        >> output += this[i].display();
        >> }
        >> if (typeof this[i] == 'string') {
        >> output += i + ' = ' + this[i] + '\n';
        >> }
        >> }
        >> return output;
        >> }
        >>
        >> bookObject.prot otype.display = _displayObjectP ropertiesAndMet hods;
        >> authorObject.pr ototype.display = _displayObjectP ropertiesAndMet hods;
        >>
        >> function cloneObject(wha tObject) {
        >> for (i in whatObject) {
        >> if (typeof whatObject[i] == 'object') {
        >> this[i] = new cloneObject(wha tObject[i]);
        >> }
        >> else
        >> this[i] = whatObject[i];
        >> }
        >> }
        >>
        >> // Example code on how to clone....
        >>
        >> var author1 = new authorObject('D avid','Flanagan ')
        >>
        >> var book1 = new bookObject('Jav aScript The Definitive
        >> Guide',author1, "O'Reilly", '1-56592-234-4','2nd Edition');
        >>
        >> var book2 = new cloneObject(boo k1);
        >>
        >> book2.edition = '3rd Edition';
        >> book2.isbn = '1-56592-392-8';
        >>
        >> var book3 = new cloneObject(boo k2);
        >>
        >> book3.edition = '4rd Edition';
        >> book3.isbn = '0-596-00048-0';
        >>
        >> alert(book1.dis play());
        >> alert(book2.dis play());
        >> alert(book3.dis play());
        >>
        >> </script>[/color]
        >
        >or:
        >
        >Object.prototy pe.clone = function() { return this.valueOf(); }
        >
        >//seems to work okay[/color]

        Hmm I put the following near the end of the above script just before
        the alerts.

        Object.prototyp e.clone = function() { return this.valueOf(); }

        var book4 = book3.clone();

        book4.edition = 'Object Clone';
        book4.isbn = '1-234-56789-X';

        alert(book1.dis play());
        alert(book2.dis play());
        alert(book3.dis play());
        alert(book4.dis play());


        But book3 now displays the same edition name & isbn as book4 so it
        looks like book4 points to the "same" object as book3 not a new
        totally different object.

        is this how your "clone" function is ment to work?

        Thanks

        Al.


        Comment

        • Michael Winter

          #5
          Re: Copy an Object?

          On Tue, 03 Aug 2004 13:49:22 +0100, Harag <haragREMOVECAP S@softhome.com>
          wrote:
          [color=blue]
          > On Tue, 03 Aug 2004 05:53:28 -0500, Fox <fox@fxmahoney. com> wrote:
          >[color=green]
          >> Harag wrote:[/color][/color]

          [snip]
          [color=blue][color=green][color=darkred]
          >>> NVM, I've found a solution... not sure if its the perfect way, so if
          >>> anyone has a better way then please advise.[/color][/color][/color]

          It probably is the best way, though you could combine it with Fox'
          suggestion:

          Object.prototyp e.clone = function() {
          var o = new Object(), p;

          for(p in this) {
          if('object' == typeof this[p]) {
          o[p] = this[p].clone();
          } else {
          o[p] = this[p];
          }
          }
          return o;
          }

          I would think that

          var newBook = book.clone();

          looks better than

          var newBook = new cloneObject(boo k);

          Also, notice that you didn't declare 'i' in your constructor, so that
          would have been global.

          If you want to clone arrays as well, you could use this in addition to the
          code above:

          Array.prototype .__clone = Array.prototype .clone;
          Array.prototype .clone = function() {
          var i, o = this.__clone();

          for(i = 0; i < length; ++i) {
          o[i] = this[i];
          }
          }

          [snip]

          Just so you know: I haven't tested these.

          Mike


          Please remember to trim your quotations!

          --
          Michael Winter
          Replace ".invalid" with ".uk" to reply by e-mail

          Comment

          • Lasse Reichstein Nielsen

            #6
            Re: Copy an Object?

            Harag <haragREMOVECAP S@softhome.com> writes:

            [objects copied as reference values][color=blue]
            > unlike
            >
            > var a = 20;
            > var b= a;
            >
            > Which creates a copy of the variable "a" and stores it in variable
            > "b".[/color]

            Not really. Or rather, it's impossible to tell. (And it doesn't copy
            the *variable*, but the *value* that variable refers to).

            Objects have identity. Two object with identical properties can still
            test different when compared with "==". A simple number, boolean or
            string does not have identity. One "20" is no different from another
            "20". And there is a good reason for that.

            Simple values are immutable. If you have the number 20, there is no
            way to *change* the value. You can put another in its place, but the
            value itself is always the same. Objects, on the other hand, are
            mutable. You can add, remove or change properties of an object. That
            makes two objects distinguishable : if you add a property to one, it
            won't be on the other.

            Even if simple values were copied by reference, you wouldn't be able
            to tell, because they are not distinguishable in any way. Most likely,
            strings are passed around as references instead of copying their
            contents. With an immutable value, you don't need to know :)
            [color=blue]
            > How can I copy my above object into a new variable rather than
            > reference the same object ? What I want to do is create the object, do
            > a load of property changes, then copy the object into a new variable
            > and do a load more property changes.[/color]

            The simple method is to just create a new object and copy all enumerable
            properties:
            ---
            function copyObject(oldO bject) {
            var newObject = new Object();
            for (var propName in oldObject) {
            newObject[propName] = oldObject[propName];
            }
            return newObject;
            }
            ---
            A sometimes more efficient method would let the new object inherit
            from the old:
            ---
            function cloneObject(old Object) {
            function Dummy(){};
            dummy.prototype = oldObject;
            return new Dummy();
            }
            ---
            With this latter approach, later changes to oldObject will be visible
            on newObject as well, unless overwritten by changes to newObject.

            Example:
            ---
            var o1 = {x:42, y:37, z:"a test"};
            var o2 = cloneObject(o1) ;
            o1.x = "Foo";
            o2.y = "Bar";
            o1.y = "Baz";
            alert(o2.x + o2.y); // alerts FooBar
            ---

            /L
            --
            Lasse Reichstein Nielsen - lrn@hotpop.com
            DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleD OM.html>
            'Faith without judgement merely degrades the spirit divine.'

            Comment

            • Lasse Reichstein Nielsen

              #7
              Re: Copy an Object?

              "Michael Winter" <M.Winter@bluey onder.co.invali d> writes:
              [color=blue]
              > for(p in this) {
              > if('object' == typeof this[p]) {
              > o[p] = this[p].clone();[/color]

              That would make a "deep copy". A shallow copy would not need this
              distinction. Which one is desired would depend on how it's going to be
              used.[color=blue]
              > }[/color]
              [color=blue]
              > I would think that
              >
              > var newBook = book.clone();
              >
              > looks better than
              >
              > var newBook = new cloneObject(boo k);[/color]

              The only irritation is that during the "for (p in ..." loop, "p" will
              at some point be "clone", so the clone function is copied for no
              real reason.

              /L
              --
              Lasse Reichstein Nielsen - lrn@hotpop.com
              DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleD OM.html>
              'Faith without judgement merely degrades the spirit divine.'

              Comment

              • Mick White

                #8
                Re: Copy an Object?

                Michael Winter wrote:
                [color=blue]
                > [snip]
                > If you want to clone arrays as well, you could use this in addition to
                > the code above:
                >
                > Array.prototype .__clone = Array.prototype .clone;
                > Array.prototype .clone = function() {
                > var i, o = this.__clone();
                >
                > for(i = 0; i < length; ++i) {
                > o[i] = this[i];
                > }
                > }[/color]

                Array.prototype .clone = function() {
                return this.slice(0)
                }
                Works for me.
                Mick
                [color=blue]
                >
                > [snip]
                >
                > Just so you know: I haven't tested these.
                >
                > Mike
                >
                >
                > Please remember to trim your quotations!
                >[/color]

                Comment

                Working...