Your Search Results

    Defining Functions

    This article is in need of a technical review.

    Passing by value vs. by reference

    I teach programming and find this to be a most interesting discussion point. I will set the scene and explain the confusion.

    Variable names, in JavaScript are just that, names. They point at objects that have type.

    When the type is primitive, the name points directly at the datum. When the type is non-primitive, the name points at a location in memory (a "locker number") where the actual object is stored.

    The name of an object works like a telephone number. It is the handle by which you communicate with the object. When an object is primitive, you can only ask for its datum. When an object is not primitive, you can "send it a message" via its name. The name is not responsible for knowing what the message is to do: that responsibility lies with the object.

    All functions in Java and JavaScript are pass-by-value. The important thing we ask is: What do they pass? A copy of the datum pointed at by the name is passed.

    For a primitive type, that is the actual "thing" the name is referring to. For instance, if you have

    var x = 5;
    ..... f(x);

    then a copy of the value 5 being pointed to by the variable x is passed to f. No matter what f does, x will be unaffected back in the calling routine.

    This situation tempts people to say that JavaScript is "pass by reference".

    function switch(x){
    var tmp = x[0];
    x[0] = x[1];
    x[1] = tmp;
    var arr = [1,2,3];
    //now arr points at [1,2,3]
    //now array points at [2,1,3].

    What is passed to switch? The "locker number" containing the array! A copy of this is passed. The array changes. Sure. It does so for the following reason. Imagine your house is white and you give someone a copy of your address and say, "paint the house at this address pink." You will come home to a pink house. What we have just seen is the "pink house" effect.

    Contrast that with this.

    function trash(x)
    x = [0];
    var arr = [1,2,3]
    //arr points at [1,2,3]
    //whoa! arr still points at [1,2,3]

    Imagine you give someone a copy of your address and you tell them, "Change this to 1400 Pennsylvania Ave, Washington, DC." Will you now reside in the White House? No. Changing a copy of your address in no way changes your residence.

    Calling a mutator method on a passed object is essentially what happens in the pink house situation. In particular, this "pass by reference" cannot occur on an immutable object.

    older discussion

    PauloAugusto: I think the prose about by-value parameters was correct before your rewrite. It's true that you can change the passed object's properties, but the "object reference" is itself passed by value:

    > function x(o) { o = {a:2} }
    > var obj = {a:1}
    > x(obj)
    > print(obj.a)

    -- Nickolay 02:03, 15 September 2007 (PDT)

    "All parameters are passed by value ..." is wrong and it misleaded me the first time i read it. Only primitives are passed by value, all others are passed by reference.

    Also, the description of what it means to pass "by value" is poor. At the moment it is like saying that if you turn on switch x, light bulb y turns on. The same goes for the explanation of how "by reference" works. There are no special rules that say that, when passed "by reference", changes are seen outside the calling function. The truth is that the reference to the object is passed to the function and, when the function accesses that variable, it is, in fact, accessing the same object. Nothing magical happens based on some arbitrary rules.

    Also of note, you mention that "the "object reference" is itself passed by value". As far as i know, that is the exact definition of passing "by reference".
    --PauloAugusto 17-9-2007, the one who knows nothing about wikies, bhá!

    Well, I couldn't find anything authoritative on this issue, but my feeling (based on C++ background) is that this is not called 'passing by reference'. Here's an article by someone else who thinks like me: (the article is about java, but the idea is the same -- see the swap test). --Nickolay 20:46, 17 September 2007 (PDT)

    In "C" terms:

    > Function (aVariable); //This is Pass by Value. Function will receive a copy of "aVariable".
    > Function (&aVariable); //This is Pass by Reference. Function will receive a memory address, a 'value' indicating where that variable is stored, the "reference".

    In Javascript, a number is passed by value (or by copy, if you prefer). A object is automatically passed by reference, without the need to specifically state it with the char '&' like in C/C++.
    Objects are *not* passed to functions by value, unlike it is stated in the explanation and like that very same example shows... The explanation is wrong!
    English is a very undefined language, unlike most programing languages (often based on it). I hate it when there is the need to write stuff that need to be very clear.
    -- Paulo Augusto, 18-9-2007

    What happens is that an 'object reference' is passed by value. This is somewhat similar to passing a pointer to an object in C++. It is not the same as 'passing by reference' -- in my book at least.
    void f(Foo* ptr) { Foo a; ptr = &a; }
    Foo *z; f(z); // the value of z gets copied (to ptr), 
                  // then ptr is modified, but z is not changed
                  // you can change z's state via the pointer
    void f(Foo& ref) { Foo a("another"); ref = a; }
    Foo z; f(z); // z is modified
    function f(o) { o = {} }
    var z = {a:1}; z(o); // o is not changed

    The reason I didn't want to call it 'passing by reference' is because JS doesn't behave the same as the second C++ snippet above. Also because this is a terminology issue, and this guide didn't call it passing by reference.

    Perhaps you're right and it would be clearer to JS devs if it was called 'passing by reference'. I updated the page to say that "a reference to the object is passed to the function" -- without using the vague "the object is passed by reference". Is this good enough for you? --Nickolay 04:50, 21 September 2007 (PDT)

    Thanks, it is properly explained, now.
    To note, i wouldn't complaint if you didn't called it "pass by reference" (passing the pointer). My issue was calling it "pass by value" (passing a copy of it) or something that leads into thinking that it would pass a copy.

    Also, to note, i think you misinterpreted the first example. It behaves like it should. I can't say about the 2nd example of the "reference" (which, now that you mention, i understand why you had troubles with the terminology pass by "reference"), since i don't know references in C++ very well. About the first example, if you wanted to change z, you would need this code, instead:

    void f(Foo **ptr) { Foo a; (*ptr) = &a; }
    Foo *z; f(&z);

    I haven't tested, since i am in another computer, but i am pretty sure it must be it or something very similar (although you would have troubles with this code, since z would be pointing to a mem address where it was stored "Foo", which is a local variabel which will get "destroied" as soon as execution leaves the function f() ).

    About your JavaScript example, i don't understand exactly what the "o = {}" is suposed to do but i think that the problem is what you are expecting it to do (it doesn't seems to override neither will it add, if you change it to "o={b:3}"). This JavaScript still works and proves that a reference or pointer or whatever is passed to the function:

    function f (obj)
        obj.a= 2;
    var qwe= {a:1};
    alert (qwe.a);
    f (qwe);
    alert (qwe.a);

    There are still some things that could need better explaining.

    (Paulo Augusto, 9-10-2007)

    Document Tags and Contributors

    Contributors to this page: ethertank, khyamay, Nickolay, Ncmathsadist, PauloAugusto
    Last updated by: khyamay,