3

I don't understand how this scope works. How does the value of eg.i get modified in first when it is only modified in second?

EXAMPLE

var obj = {

    first: function() {

        var eg = {i: 0}; // eg equals 0 here

        obj.second(eg);
        obj.second(eg);

        console.log(eg.i); // 2
    },

    second: function(eg) {

        ++eg.i;
    }
};

How does eg.i get modified in the first function as well?

user2251919
  • 665
  • 2
  • 11
  • 23

3 Answers3

4

When objects are passed in to functions in JS, they're passed in as references rather than values: http://snook.ca/archives/javascript/javascript_pass

Ahmed Nuaman
  • 12,662
  • 15
  • 55
  • 87
  • But non objects are passed by value? – user2251919 Jun 02 '13 at 20:11
  • Correct. If you pass a JS function a string argument, for example, then this is passed as a value rather than a reference. Imagine that an object exists in memory and all the function gets is a pointer to that object. – Ahmed Nuaman Jun 02 '13 at 20:14
  • Ok cool, the article explained it well, long story short primitives by value, objects by reference, thank you – user2251919 Jun 02 '13 at 20:15
  • 3
    It's incorrect to say that it's passed by reference, as there's no such thing in js. It's more correct to say that they're passed by reference *value*. For more, see Pointy's answer that Blender linked to. – Zirak Jun 02 '13 at 20:20
4

As noted in my comment to Ahmed Nuaman's answer, saying that the argument is passed by reference is incorrect. Proving that is trivial:

function change (x) {
    //"replace" x with a different object?
    x = {
        a : 4
    };
}
var o = { a : 6 };
change(o);
console.log(o.a); //6

If the argument would truly have been passed by reference, o.a would have been 4. However, the argument is passed by the reference value - in this case, the value is simply and object.

And that's why you observed the symptoms presented in the question: When you directly modified the argument, the object passed in was changed.

It's as if you got some ice-cream, then went back to the stand to ask for an extra scoop of vanilla. You still have the same cup, but with that extra something. Using that analogy in the example above, you ask for a new vanilla ice-cream: you still have the old one, and that hasn't changed (well, it may have melted a bit). In a pass-by-reference scenario, you would've dumped your existing ice-cream, and got a brand new one.

As a final note: This is not about scoping rules in js. If eg wasn't passed to the second function, it would've been unavailable to it.

Zirak
  • 38,920
  • 13
  • 81
  • 92
3

You're passing eg as a parameter to second. It might be easier to see if you renamed it:

second: function(x) {
    ++x.i;
}

It gets modified in the first function because you modify it with the second function.

Blender
  • 289,723
  • 53
  • 439
  • 496