byVal equivalent for JavaScript?

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

    byVal equivalent for JavaScript?

    How would I pass an object variable to a function without that variable
    getting changed in the function changing the variable that was passed (eg
    both variables treated as one)?

    <script>
    var a = 1;
    var b = 2;
    function sub(a, b)
    {
    a = a - b;
    return a;
    }
    document.write( "a = " + a + "<br>");
    document.write( "b = " + b + "<br>");
    document.write( "sub(a, b) = " + sub(a, b) + "<br>");
    document.write( "a = " + a + "<br>");
    document.write( "b = " + b + "<p>");

    var a = new Object();
    a.val = 1;
    var b = new Object();
    b.val = 2;
    function subo(a, b)
    {
    a.val = a.val - b.val;
    return a.val;
    }
    document.write( "a = " + a.val + "<br>");
    document.write( "b = " + b.val + "<br>");
    document.write( "subo(a, b) = " + subo(a, b) + "<br>");
    document.write( "a = " + a.val + "<br>");
    document.write( "b = " + b.val + "<br>");
    </script>

    the above script outputs:
    a = 1
    b = 2
    sub(a, b) = -1
    a = 1
    b = 2
    a = 1
    b = 2
    subo(a, b) = -1
    a = -1 <= I want this to still be 1
    b = 2


    thanks in advance


  • Erwin Moller

    #2
    Re: byVal equivalent for JavaScript?

    neerolyte wrote:
    [color=blue]
    > How would I pass an object variable to a function without that variable
    > getting changed in the function changing the variable that was passed (eg
    > both variables treated as one)?
    >
    > <script>
    > var a = 1;
    > var b = 2;
    > function sub(a, b)
    > {
    > a = a - b;
    > return a;
    > }
    > document.write( "a = " + a + "<br>");
    > document.write( "b = " + b + "<br>");
    > document.write( "sub(a, b) = " + sub(a, b) + "<br>");
    > document.write( "a = " + a + "<br>");
    > document.write( "b = " + b + "<p>");
    >
    > var a = new Object();
    > a.val = 1;
    > var b = new Object();
    > b.val = 2;
    > function subo(a, b)
    > {
    > a.val = a.val - b.val;[/color]

    This is your problem.
    Over here you change the value of val in Object a.
    What do you Javascript expect to do?
    Why did you code that line?

    Why not remove that line and just return?
    return a.val - b.val;

    That should work.

    Regards,
    Erwin Moller

    Comment

    • neerolyte

      #3
      Re: byVal equivalent for JavaScript?

      [color=blue]
      > This is your problem.
      > Over here you change the value of val in Object a.
      > What do you Javascript expect to do?
      > Why did you code that line?
      >
      > Why not remove that line and just return?
      > return a.val - b.val;[/color]
      no, because this is just demo code to demonstrate the problem, the real code
      has just made it to 310 lines, so i figured it wouldn't be nice to post it,
      i have a solution that involves making a new object, and transfering all the
      values individualy, this works but seems rather pointless if there is
      something equivalent to byVal


      Comment

      • Brian Genisio

        #4
        Re: byVal equivalent for JavaScript?

        neerolyte wrote:
        [color=blue][color=green]
        >>This is your problem.
        >>Over here you change the value of val in Object a.
        >>What do you Javascript expect to do?
        >>Why did you code that line?
        >>
        >>Why not remove that line and just return?
        >>return a.val - b.val;[/color]
        >
        > no, because this is just demo code to demonstrate the problem, the real code
        > has just made it to 310 lines, so i figured it wouldn't be nice to post it,
        > i have a solution that involves making a new object, and transfering all the
        > values individualy, this works but seems rather pointless if there is
        > something equivalent to byVal
        >
        >[/color]

        I have never met a language that it is a good idea to pass any large
        object or structure by value. If your object is of any size, you
        _should_ be passing by reference, and scrap the idea of passing it by
        value.

        Brian

        Comment

        • neerolyte

          #5
          Re: byVal equivalent for JavaScript?

          > I have never met a language that it is a good idea to pass any large[color=blue]
          > object or structure by value. If your object is of any size, you
          > _should_ be passing by reference, and scrap the idea of passing it by
          > value.[/color]
          the objects consist of an array of numbers, (array varies in size from 1 to
          40 in length, average around 20), and a true or false value.
          I don't think this is particularly large, but atleast one of the functions
          needs to have the original values that were passes to it, close to the end
          of it, so passing by referance is out of the question.



          p.s. i did mean to send this to the news group and not just you Brian,
          sorry.


          Comment

          • Brian Genisio

            #6
            Re: byVal equivalent for JavaScript?

            neerolyte wrote:
            [color=blue][color=green]
            >>I have never met a language that it is a good idea to pass any large
            >>object or structure by value. If your object is of any size, you
            >>_should_ be passing by reference, and scrap the idea of passing it by
            >>value.[/color]
            >
            > the objects consist of an array of numbers, (array varies in size from 1 to
            > 40 in length, average around 20), and a true or false value.
            > I don't think this is particularly large, but atleast one of the functions
            > needs to have the original values that were passes to it, close to the end
            > of it, so passing by referance is out of the question.
            >
            >
            >
            > p.s. i did mean to send this to the news group and not just you Brian,
            > sorry.
            >
            >[/color]

            The rule I follow: If the data I am passing to a function is any larger
            than the size of a pointer (If the language even has one), I always pass
            by reverence or by pointer.

            Something with 20 items is really large to pass on the stack. The
            compiler will make a copy of it anyways, when you pass by reference, so
            if you really need to make a copy of the data when it comes, you are not
            doing anything out of the ordinary. Making a copy of an array only
            takes two lines anyways, so why not just make a copy when you get the
            array passed to you?

            I have never encountered a language that lets you pass an array, and all
            of it's elelments by value.

            Here, in Javascript, you are sending an Array object over... if it is by
            reference, or by value, it does not matter, since any object in the
            array is referenced by the Array object... In other words, A reference
            to an Array Object, or a copy of an Array object will always point to
            the same set of objectes within the Array object.

            If you need to modify the array AND use the original values in the
            array, after they have been modified, you NEED to make a copy of it.

            I know it is not the answer you are looking for, but there really is no
            other way.

            Brian

            Comment

            • neerolyte

              #7
              Re: byVal equivalent for JavaScript?

              > The rule I follow: If the data I am passing to a function is any larger[color=blue]
              > than the size of a pointer (If the language even has one), I always pass
              > by reverence or by pointer.
              >
              > Something with 20 items is really large to pass on the stack. The
              > compiler will make a copy of it anyways, when you pass by reference, so
              > if you really need to make a copy of the data when it comes, you are not
              > doing anything out of the ordinary. Making a copy of an array only
              > takes two lines anyways, so why not just make a copy when you get the
              > array passed to you?
              >
              > I have never encountered a language that lets you pass an array, and all
              > of it's elelments by value.
              >
              > Here, in Javascript, you are sending an Array object over... if it is by
              > reference, or by value, it does not matter, since any object in the
              > array is referenced by the Array object... In other words, A reference
              > to an Array Object, or a copy of an Array object will always point to
              > the same set of objectes within the Array object.
              >
              > If you need to modify the array AND use the original values in the
              > array, after they have been modified, you NEED to make a copy of it.
              >
              > I know it is not the answer you are looking for, but there really is no
              > other way.
              >
              > Brian
              >[/color]
              thankyou for your time and patience, i have not ye, but i will modify the
              functions to not use my pass by val work around.
              thanks for the tips


              Comment

              • Martin Honnen

                #8
                Re: byVal equivalent for JavaScript?



                Brian Genisio wrote:
                [color=blue]
                > I have never encountered a language that lets you pass an array, and all
                > of it's elelments by value.[/color]

                Off topic here, but PHP (4 at least) will pass arrays by value (unless
                you explictly pass by reference).
                --

                Martin Honnen


                Comment

                • Dr John Stockton

                  #9
                  Re: byVal equivalent for JavaScript?

                  JRS: In article <3ffd7f5b$1@ola f.komtel.net>, seen in
                  news:comp.lang. javascript, Martin Honnen <mahotrash@yaho o.de> posted at
                  Thu, 8 Jan 2004 17:03:35 :-[color=blue]
                  >
                  >
                  >Brian Genisio wrote:
                  >[color=green]
                  >> I have never encountered a language that lets you pass an array, and all
                  >> of it's elelments by value.[/color]
                  >
                  >Off topic here, but PHP (4 at least) will pass arrays by value (unless
                  >you explictly pass by reference).[/color]

                  Also Pascal, Delphi, IIRC Algol 60; and therefore maybe Algol68 and
                  probably Modula 2. A good language should provide both, since either
                  may be needed; and should have either a well-chosen default or none.

                  --
                  © John Stockton, Surrey, UK. ?@merlyn.demon. co.uk Delphi 3 Turnpike 4 ©
                  <URL:http://www.merlyn.demo n.co.uk/> TP/BP/Delphi/&c., FAQqy topics & links;
                  <URL:http://www.bancoems.co m/CompLangPascalD elphiMisc-MiniFAQ.htm> clpdmFAQ;
                  <URL:http://www.borland.com/newsgroups/guide.html> news:borland.* Guidelines

                  Comment

                  • Thomas 'PointedEars' Lahn

                    #10
                    Re: byVal equivalent for JavaScript?

                    neerolyte wrote:
                    [color=blue]
                    > How would I pass an object variable to a function without that variable
                    > getting changed in the function changing the variable that was passed (eg
                    > both variables treated as one)?[/color]

                    If you pass a reference to a method and modify properties of
                    the reference, you modify the object that it references.
                    [color=blue]
                    > <script>[/color]

                    <script type="text/javascript">

                    is valid HTML 4.
                    [color=blue]
                    > var a = 1;
                    > var b = 2;
                    > function sub(a, b)
                    > {
                    > a = a - b;
                    > return a;
                    > }[/color]

                    This works and leaves "a" unchanged because "a" is the identifier of
                    a named function argument and thus a variable of the local execution
                    context (in short: a local variable). If you would have written
                    this.a instead, you would have referenced the global "a" if sub(...)
                    was not called as a method of another object than the global one.
                    [color=blue]
                    > var a = new Object();
                    > a.val = 1;
                    > var b = new Object();
                    > b.val = 2;
                    > function subo(a, b)
                    > {
                    > a.val = a.val - b.val;
                    > return a.val;
                    > }
                    > [...]
                    > document.write( "subo(a, b) = " + subo(a, b) + "<br>");
                    > [...][/color]

                    This changes the value of a.val because you pass "a", a reference to
                    *a* global object (which is in fact a property of *the* global object),
                    as argument of the method. So the global "a" is assigned to the local
                    "a", thus it refers to the same object and the property of the object
                    it refers to, is of course changed by the assignment.

                    The solution is obvious: Do not assign anything to properties of
                    arguments if you want them unchanged. Instead, copy the value of
                    that property in a local variable and manipulate that variable,
                    *e.g.*:

                    function subo(a, b)
                    {
                    var x = a.val;
                    x = a.val - b.val;
                    return x;
                    }


                    HTH

                    PointedEars

                    P.S.: Your "From:" header is borken, read
                    <http://www.interhack.n et/pubs/munging-harmful/>

                    Comment

                    Working...