1

My basic understanding is that JavaScript runs from top to bottom, returning to functions when they are called, but then proceeding to the next line of code after calling a function.

That makes sense when I look at this code as an example:

var a = 5;
var b = a;
a = 2;
console.log(b);
// My expected output 5, works as expected

I get lost when I look at this though:

var a = [5];
var b = a;
a.push(2);
console.log(b);
// My expected output [5], instead returns [5,2]

If I assigned the var b the value of a when it was 5, why does the value of b change to [5,2] when 2 wasn't pushed to a until the NEXT line?

I'm obviously missing some basic fundamentals here.

  • 1
    Maybe this can help https://stackoverflow.com/questions/6605640/javascript-by-reference-vs-by-value – AnAmuser Mar 10 '18 at 21:35
  • Objects (and arrays are objects in JavaScript) are passed by reference-- so you're not pointing`b` to the value of `a` at that time, you're pointing `b` to the array that `a` is referencing, so any mutation to that array will be visible to all variables pointing to that object/array. – Alexander Nied Mar 10 '18 at 21:36
  • Possible duplicate of [JavaScript array assign issue](https://stackoverflow.com/questions/26745170/javascript-array-assign-issue) – Ele Mar 10 '18 at 21:41
  • Variable `a` and `b` are pointing to the same value in memory, so every change on `a` will modify `b`. – Ele Mar 10 '18 at 21:42

3 Answers3

1

The reason why you see [5, 2] is because:

  • b is a reference to a
  • so when you edit a, b will reflect those changes as b points to a

In a nutshell, complex objects (i.e., arrays and objects) in JavaScript are passed by reference, whereas primitives by value:

  • this has primarily performance benefits. For instance, think of having a large object---every time you pass that object you would end up making copies of it, which is probably not a good idea
  • fortunately, there are ways of performing deep object cloning. Here is a resource on this: How do I correctly clone a JavaScript object?
  • a thing to keep in mind: only when there are no more active references to an object, the chunk of memory allocated to that object gets reclaimed during the garbage collection (i.e., check What is JavaScript garbage collection?)

Here is a good discussion related to your question: Is JavaScript a pass-by-reference or pass-by-value language?

Hope it helps.

Mihai
  • 2,807
  • 4
  • 28
  • 53
0

You are pushing 2 onto the array and since b points to a, the output from console.log(b) outputs [5,2] instead of 5.

rshelat
  • 81
  • 1
  • 1
  • 3
0

a and b still contain the same array.

The issue is that a.push(2); does not assign a new value to a; instead it modifies the actual array stored in a. Because b contains the same array, any modification to it is visible through both a and b.

This issue does not arise with so-called "primitive" types like numbers because numbers have no mutable structure. You cannot modify 2 to suddenly be 5011, but you can modify an array to have a different size and different contents.

melpomene
  • 84,125
  • 8
  • 85
  • 148