-2

I've searched about call by reference on javascript but still am confused.

consider this code.

let arr = [];
let temparr = [2,3,4];
arr = temparr;
temparr.push(5);
console.log(arr);   //[2,3,4,5]
console.log(temparr); //[2,3,4,5]


let arr2 = [];
let temparr2 = [2,3,4];
arr2 = temparr2;
temparr2 = [1,2];
console.log(arr2);  //[2,3,4]
console.log(temparr2);   /[1,2]

For the first case, arr gets affected by temparr due to arr = temparr, however, in the second example, arr2 does not get affected by modification in temparr2. My question is,

  1. In the first example, Why in the first place is arr getting affected by the modification of temparr? Is this in the line of call by reference? If so, on what occasions does it trigger such operation?

  2. In the second example, the only difference is that i did not use push but assign new array to modify the temparr2. However this time arr2 did not get affected. What is the difference with the first example?

Thank you very much

Eric Ahn
  • 391
  • 2
  • 7
  • 18
  • 2
    No. Please search. It is cleanly described as “call by (object) sharing” with the implementation of “call by value”. Ref. Wikipedia. – user2864740 May 02 '19 at 17:12
  • arrays are pass by reference in javascript yes, but you've answered your own question. when you assigned a new array to `temparr2`, of course the previous values of `arr2` are not included in `temparr2`. not sure why you expected any different – r3wt May 02 '19 at 17:13
  • @r3wt No, arrays are not passed by reference in JavaScript. Everything is passed by Value. See the duplicate question link. – Scott Marcus May 02 '19 at 17:15
  • 1
    Possible duplicate of [Is JavaScript a pass-by-reference or pass-by-value language?](https://stackoverflow.com/questions/518000/is-javascript-a-pass-by-reference-or-pass-by-value-language) – adiga May 02 '19 at 17:35
  • @ScottMarcus arrays are pass by reference in Javascript, because when you pass an object, you are actually passing a reference to it, and an array is of course just an object under the hood. here is a jsfiddle which proves that array is pass by reference -> https://jsfiddle.net/c93ab4vs/ – r3wt May 02 '19 at 17:38
  • @r3wt That's not correct. [Please read this](https://stackoverflow.com/questions/42045586/whats-the-difference-between-a-boolean-as-primitive-and-a-boolean-as-property-o/42045636#42045636). The variable may ***hold*** a reference, but that reference is ***passed*** by Value. It's very common to conflate what the variable holds with how that value is passed. – Scott Marcus May 02 '19 at 18:13
  • @ScottMarcus it holds a reference, so therefore it is a reference(practically speaking, you could say it is pass by reference) and is mutable, which is the entire purpose of distinguishing between the two as a programmer, to determine if the value is mutable beyond the scope of the function. – r3wt May 02 '19 at 19:03
  • @r3wt No, sorry, that's just not correct. You need to separate the concept of what the variable holds from how that value (whatever it may be) is passed. Holding and passing are two distinct concepts that are often confused with each other. It is entirely possible (and, in fact how it works) to pass a reference type by value. That is not called pass by reference - - that's pass by value. The practical implications of this may only be what you care about, but labeling the process incorrectly only adds more confusion. – Scott Marcus May 02 '19 at 19:17
  • @ScottMarcus ok so the implementation is passing a value holding the reference, and not passing the reference directly. i'm not sure if what the implication of that is, but for practical purposes, do i even need to care? i don't see why it adds confusion to talk about it this way, practically speaking. so maybe you can enlighten me further on the matter. i'm genuinely curious – r3wt May 02 '19 at 20:15
  • 2
    @r3wt Yes, you do need to care because passing a reference type by reference enables the called function to replace the object to which the reference parameter refers in the caller. The storage location of the object is passed to the function as the value of the reference parameter. If you change the value in the storage location of the parameter (to point to a new object), you also change the storage location to which the caller refers. Essentially, if you could do this, you'd have a capability that you don't get with pass by value. – Scott Marcus May 03 '19 at 12:36

1 Answers1

1

Your question has less to do with how arguments are passed (everything is passed by Value all the time in JavaScript, by the way) and more to do with how Objects are stored.

In your first example, the line most relevant to your question is this:

arr = temparr;

Here, you are setting up a second variable to hold the same value as the first, but Object variables don't hold the Object, they hold the location in memory to where the object is stored. So, after that line, you have two variables that both point to the same, one underlying object. If either one of them modifies that underlying object, the other will see the same thing because they both point to only one object.

In your second example, you start out in a similar way with:

arr2 = temparr2;

Which, again, sets you up to have two variables that point to the same one, underlying object. But, then you do this:

temparr2 = [1,2];

Which doesn't modify the one underlying object, it simply reassigns the second variable to a different object, and now the two variables don't point to the same thing anymore.

It's really no different than saying:

x = 7;

and then saying:

x = 8;

The old value in x goes away and there's an entirely new value stored.

If you wanted to modify the underlying array, you would do that via the Array API, for example:

temparr2.splice(2,1); // Delete one item at index position 2

This is why the array was modified when you used .push() in the first example - - you were working on the object, not reassigning the variable.

Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
  • arrays and objects are technically pass by reference under the hood, and hence fully mutable by the function they are passed to. see the following fiddle for proof: https://jsfiddle.net/c93ab4vs/ Still don't believe me? Go ask Brendan Eich, the guy who invented the language and did it this way on purpose to be like Java. – r3wt May 02 '19 at 17:44
  • @r3wt That's incorrect. They are not technically pass by reference, since nothing in JavaScript is passed by reference. You are confusing what a variable holds vs. how it is passed. See my reply to your similar comment above. – Scott Marcus May 02 '19 at 18:15
  • @r3wt Also, Brendan Eich modeled the syntax of what he originally called "Live Script" after C. Java gets it's syntax from C as well. He did not attempt to make JavaScript execute like Java. You've got your history and facts wrong, unfortunately. And, unfortunately for me, I'm old enough to know this because I learned all of this at the time that it came out. – Scott Marcus May 02 '19 at 18:22
  • That may be true, but i'm just relaying what i remember from my conversation with him on twitter in 2016. he also told me he wrote the original version of LiveScript in about 10 days, which i thought was cool. So yes, i know it was originally called LiveScript. i know all the history and stuff. i'm just simply saying that you can call this pass by reference for practical purpose, which is determining if the variable is mutable beyond the function scope or not. – r3wt May 02 '19 at 19:05
  • 1
    ***you can call this pass by reference for practical purpose*** But, earlier you said: ***arrays and objects are technically pass by reference under the hood***. You can call it anything you like, but if you want to be correct and not add more confusion, you should call it what it is, which is pass-by-value and simply acknowledge the difference between what a variable holds and how that value is passed. It's actually pretty simple. – Scott Marcus May 02 '19 at 19:22
  • ok, you're right, but i maintain my opinion that in practice, the implication is that its basically the same as pass by reference, and thinking about it in that way is less confusing than worrying about it being "pass by value a reference that actually behaves as if you passed a reference for all practical purposes" – r3wt May 02 '19 at 20:21
  • @r3wt See my reply to your comment above. With ref type being passed by ref, you would gain a feature that isn't possible with pass by value. There is a difference between the two and so it's important to understand the implications of this. What's less confusing is just understanding that it's not enough to know ***how*** something is being passed, you also have to know ***what*** is being passed because the combination of those two things dictates not only what you'll wind up with, but also what you can do with it. – Scott Marcus May 03 '19 at 12:40