References Themselves Are Passed by Value

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • lkrubner@geocities.com

    References Themselves Are Passed by Value







    Is it true that Javascript has no clone() method, to pass an object by
    copy of value instead of reference?

    If I have an object and want to make an array out of all of its
    instance variables, I can loop through it and pass its values to a new
    array, and the class instances will be passed by copy and not by
    reference?





    Example 9.3: References Themselves Are Passed by Value

    // This is another version of the add_to_totals() function. It doesn't
    // work, through, because instead of changing the array itself, it
    tries to
    // change the reference to the array.
    function add_to_totals2( totals, x)
    {
    newtotals = new Array(3);
    newtotals[0] = totals[0] + x;
    newtotals[1] = totals[1] + x;
    newtotals[2] = totals[2] + x;
    totals = newtotals; // this line has no effect outside of the
    function.
    }

    Note that this rule applies not only to pass-by-reference, but also
    copy-by-reference. You can modify an object through a copy of a
    reference, but changing the copied reference itself does not affect the
    object nor the original reference to the object. This is a more
    intuitive and less confusing case, so we don't illustrate it with an
    example.

  • Richard Cornford

    #2
    Re: References Themselves Are Passed by Value

    lkrubner@geocit ies.com wrote:[color=blue]
    > Is it true that Javascript has no clone() method, to pass
    > an object by copy of value instead of reference?[/color]

    Yes.
    [color=blue]
    > If I have an object and want to make an array out of all
    > of its instance variables,[/color]

    Seems like an odd thing to do.
    [color=blue]
    > I can loop through it and pass its values to a new
    > array, and the class instances will be passed by copy
    > and not by reference?[/color]

    If you copy the values from an object's properties you will have a copy
    of those values.

    If you copy the values from object properties into an Array it is
    difficult to see how that Array could be considered a copy of an
    instance of a class (assuming we accept the use of the term "class" in a
    language that does not have classes).
    [color=blue]
    > Example 9.3: References Themselves Are Passed by Value[/color]

    If this a quote from some source it would be a good idea to make that
    obvious (and cite the source) else it reads like a very bizarre
    statement on your part.
    [color=blue]
    > // This is another version of the add_to_totals() function.
    > // It doesn't work, through, because instead of changing the
    > // array itself, it tries to change the reference to the array.[/color]

    Another example of the inappropriate use of the term "doesn't work" as
    the function will do exactly what it has been programmed to do, there
    just may be no value it its doing so.
    [color=blue]
    > function add_to_totals2( totals, x)
    > {
    > newtotals = new Array(3);
    > newtotals[0] = totals[0] + x;
    > newtotals[1] = totals[1] + x;
    > newtotals[2] = totals[2] + x;
    > totals = newtotals; // this line has no effect outside
    > // of the function.[/color]

    It has no effect outside of the function because - totals -, as a formal
    parameter, is a named property of the Activation/Variable object for the
    current execution context and that object will go out of scope as soon
    as the function returns.

    On the other hand, a global variable with the name - newtotals - is
    either created or has its value assigned by the first line in the
    function body. So while this function may have not impact on an array
    passed as the first argument to the function call it certainly will have
    an effect outside of the function.

    By the look of it that global side-effect is an error that sends strong
    negative signals when found in a text/example that has an apparent
    intent to be instructional.
    [color=blue]
    > }
    >
    > Note that this rule applies not only to pass-by-reference,
    > but also copy-by-reference.[/color]

    ?
    [color=blue]
    > You can modify an object through
    > a copy of a reference, but changing the copied reference
    > itself does not affect the object nor the original reference
    > to the object. This is a more intuitive and less confusing
    > case, so we don't illustrate it with an example.[/color]

    This reads like someone is trying to explain the behaviour of javascript
    through their own conceptual model. How appropriate that is probably
    depends on the level at which the explanation is being pitched, at least
    in part. Personally I prefer explanations that mirror the language
    specification and, in so far as the conceptual model apparently
    presented here differs form the specified behaviour of the language, it
    appears to be a source of confusion rather than explanation.

    Richard.


    Comment

    • Lasse Reichstein Nielsen

      #3
      Re: References Themselves Are Passed by Value

      lkrubner@geocit ies.com writes:

      (I'm going to be exceedingly pedantic, which I find to be necessary
      when discussing the finer points of values vs. references :)
      [color=blue]
      > Is it true that Javascript has no clone() method, to pass an object by
      > copy of value instead of reference?[/color]

      That is correct. One can be created, depending on which properties are
      desired of it, but there is no build-in operator or method that
      creates a "clone" of an object, for any reasonable meaning of "clone".
      [color=blue]
      > If I have an object and want to make an array out of all of its
      > instance variables,[/color]

      I assume that "instance variable" means what is usually called
      "property" in Javascript? :)
      [color=blue]
      > I can loop through it and pass its values to a new
      > array, and the class instances will be passed by copy and not by
      > reference?[/color]

      There are no classes in JavaScript, there are only objects. They
      inherit through prototyping instead of class inheritance.

      But no, you can't simply create copies of an object. There are
      solutions, but you must first decide what a "copy of an object" really
      means. Is it a deep or shallow copy, or merely an object with the same
      properties but where changes doesn't affect the original object? All
      three can be implemented, but in different ways.

      [color=blue]
      > Example 9.3: References Themselves Are Passed by Value[/color]
      ....[color=blue]
      > function add_to_totals2( totals, x)[/color]
      ....[color=blue]
      > totals = newtotals; // this line has no effect outside of the
      > function.[/color]
      ....
      [color=blue]
      > Note that this rule applies not only to pass-by-reference, but also
      > copy-by-reference.[/color]

      If I understand this correctly, then yes. JavaScript is purely
      pass-by-value.

      Variables cannot contain objects. They can only contain references to
      objects. These references are passed and assigned/copied as values.
      [color=blue]
      > You can modify an object through a copy of a reference, but changing
      > the copied reference itself does not affect the object nor the
      > original reference to the object.[/color]

      References are immutable values, so you can overwrite variables (or
      properties) containing them, but you can't change them. You can also
      dereference them to gain access to properties of the object they
      are referencing.
      [color=blue]
      > This is a more intuitive and less confusing case, so we don't
      > illustrate it with an example.[/color]

      Aha. :)

      /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

      • lkrubner@geocities.com

        #4
        Re: References Themselves Are Passed by Value

        Sorry I was unclear. I'd tried to look up info on the issue before I
        posted here, and I posted the article that was causing me confusion.

        In Photoshop I can get what seems like an array of all the paths in an
        image by using the pathItems() method. But I can't use methods like
        slice() on what I get, because pathItems returns an object, not an
        array. I'd like an array of all the paths so I can loop through them
        and delete all but one. However, I can't use the pathItems() object
        because the number of items would actually change as I looped through
        them. I couldn't do a normal for() loop. Not if I have an object
        holding the actual paths. But if I had a copy, an array, then I could
        loop through that and the array.length property wouldn't change as I
        went through the loop. You see? I need a copy, I can't work with direct
        references to the paths that I'm deleting.

        Comment

        • RobG

          #5
          Re: References Themselves Are Passed by Value

          lkrubner@geocit ies.com wrote:[color=blue]
          > Sorry I was unclear. I'd tried to look up info on the issue before I
          > posted here, and I posted the article that was causing me confusion.
          >
          > In Photoshop I can get what seems like an array of all the paths in an
          > image by using the pathItems() method. But I can't use methods like
          > slice() on what I get, because pathItems returns an object, not an
          > array.[/color]

          To see all the properties of your pathItmes object:

          function showProperties( obj){
          var msg=[];
          for ( prop in obj ){
          msg.push(obj[prop]);
          }
          alert(msg.join( '\n'));
          }

          and call it with:

          showProperties( pathItems);
          [color=blue]
          > I'd like an array of all the paths so I can loop through them
          > and delete all but one. However, I can't use the pathItems() object
          > because the number of items would actually change as I looped through
          > them. I couldn't do a normal for() loop. Not if I have an object
          > holding the actual paths.[/color]

          Using the above script as a starting point, test the value returned by
          obj[path] inside the for loop. If you want to delete it, set its
          value to undefined - that will remove it.
          [color=blue]
          > But if I had a copy, an array, then I could
          > loop through that and the array.length property wouldn't change as I
          > went through the loop. You see? I need a copy, I can't work with direct
          > references to the paths that I'm deleting.
          >[/color]

          Here's another example:

          <script type="text/javascript">
          var pathItems = [];
          pathItems[0] = 'Path 0';
          pathItems[1] = 'Path 1';
          pathItems[2] = 'Path 2';
          pathItems.sayHi = function(){aler t('Hi from pathItems')};

          function showProperties( obj){
          var msg=[];
          for ( path in obj ){
          msg.push(obj[path]);
          }
          alert(msg.join( '\n'));
          }

          function keepPath(obj,ke eperPath){
          for ( path in obj ){
          if (keeperPath != obj[path]){
          obj[path] = undefined;
          }
          }
          }

          alert('About to show pathItems properties');

          // Show pathItems
          showProperties( pathItems);

          // Call the sayHi method
          pathItems.sayHi ();

          alert('About to remove the sayHi method');

          // Remove the sayHi method
          pathItems.sayHi = undefined;

          // Show modified sayHi
          showProperties( pathItems);

          alert('About to remove all but \'Path 1\'');

          // Remove all but 'Path 01'
          keepPath(pathIt ems, 'Path 1');

          // Show modified sayHi
          showProperties( pathItems);

          </script>



          --
          Rob

          Comment

          • Thomas 'PointedEars' Lahn

            #6
            Re: References Themselves Are Passed by Value

            lkrubner@geocit ies.com wrote:
            [color=blue]
            > In Photoshop I can get what seems like an array of all the paths in an
            > image by using the pathItems() method. But I can't use methods like
            > slice() on what I get, because pathItems returns an object, not an
            > array.[/color]

            Arrays are Array objects in JS, i.e. objects having Array() as constructor.


            PointedEars

            Comment

            Working...