to my understanding, both array and objects are Pass By Reference based on the memory address, so if I create another variable and point to the array/object, and mutate any of the values, another value should also be changed.
However, I don't quite understand how it works here. I am pointing to array1 and modifying array1 to empty, why the value at anotherArray does not change?
var array1 = [1,2,3,4,5,6,7]; // Created array
var anotherArray = array1; // Referenced array1 by another variable
array1 = []; // Empty the array
console.log(anotherArray); // Output [1,2,3,4,5,6,7]
I can understand the below example why the anotherArray bees [] empty because it is passed by reference, but why the anotherArray still output [1,2,3,4,5,6,7] for the above?
var array1 = [1,2,3,4,5,6,7]; // Created array
var anotherArray = array1; // Referenced array1 by another variable
array1.length = 0; // Empty the array by setting length to 0
console.log(anotherArray); // Output []
Thank you.
to my understanding, both array and objects are Pass By Reference based on the memory address, so if I create another variable and point to the array/object, and mutate any of the values, another value should also be changed.
However, I don't quite understand how it works here. I am pointing to array1 and modifying array1 to empty, why the value at anotherArray does not change?
var array1 = [1,2,3,4,5,6,7]; // Created array
var anotherArray = array1; // Referenced array1 by another variable
array1 = []; // Empty the array
console.log(anotherArray); // Output [1,2,3,4,5,6,7]
I can understand the below example why the anotherArray bees [] empty because it is passed by reference, but why the anotherArray still output [1,2,3,4,5,6,7] for the above?
var array1 = [1,2,3,4,5,6,7]; // Created array
var anotherArray = array1; // Referenced array1 by another variable
array1.length = 0; // Empty the array by setting length to 0
console.log(anotherArray); // Output []
Thank you.
Share Improve this question asked Dec 18, 2021 at 20:09 cHappinesscHappiness 634 bronze badges 4-
1
In the first sample you are not modifying the array that
array1
refers to, you are reassigning whatarray1
refers to. In the second sample you are modifying the array thatarray1
refers to – UnholySheep Commented Dec 18, 2021 at 20:11 - What is the difference between reassigning vs modifying in the above examples? Thanks – cHappiness Commented Dec 18, 2021 at 20:16
- In order the relationship to exist, both arrays should coexist. If you remove or redefine one of them the relationship goes puff.. – Redu Commented Dec 18, 2021 at 20:17
-
1
There's no such thing as pass by reference in JS, everything is passed by value. It just so happens that for objects/arrays, the value itself is a reference. When you do
array1 = []
, you're simply replacing the value. – Lennholm Commented Dec 18, 2021 at 20:27
5 Answers
Reset to default 3Assigning to a variable never changes the object that the variable previously had as value.
Objects -- such as arrays -- only change when you mutate them, either through calling a method that does this, or by setting a property.
Here is a visualisation of your first script:
var array1 = [1,2,3,4,5,6,7]
results in this:
array1
↓
┌──────┬───┬───┬───┬───┬───┬───┬───┐
│length│ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │
├──────┼───┼───┼───┼───┼───┼───┼───┤
│ 7 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │
└──────┴───┴───┴───┴───┴───┴───┴───┘
After var anotherArray = array1
we have this:
array1
↓
┌──────┬───┬───┬───┬───┬───┬───┬───┐
│length│ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │
├──────┼───┼───┼───┼───┼───┼───┼───┤
│ 7 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │
└──────┴───┴───┴───┴───┴───┴───┴───┘
↑
anotherArray
Then array1 = []
will create a new array: so there are now two arrays. It also makes array1
a reference for the newly created array:
array1
↓
┌──────┐
│length│
├──────┤
│ 0 │
└──────┘
┌──────┬───┬───┬───┬───┬───┬───┬───┐
│length│ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │
├──────┼───┼───┼───┼───┼───┼───┼───┤
│ 7 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │
└──────┴───┴───┴───┴───┴───┴───┴───┘
↑
anotherArray
In the second script the assignment to the length
property (actually a setter) will mutate the array. There is no new array created, and the values 1,2,3,4,5,6,7 are lost:
array1
↓
┌──────┐
│length│
├──────┤
│ 0 │
└──────┘
↑
anotherArray
For your first example, you are actually making a reassignment to array1 as an empty array (and now they are pointing to 2 different arrays in the memory), hence the anotherArray remains unchanged.
var array1 = [1,2,3,4,5,6,7]; // Created array
var anotherArray = array1; // Referenced array1 by another variable
array1 = []; // Empty the array
console.log(anotherArray); // Output [1,2,3,4,5,6,7]
In this case, you are actually modifying the array by assigning it's length to 0. since array1 refers to it, it impacts on him as well since they are referring the same array in the memory.
var array1 = [1,2,3,4,5,6,7]; // Created array
var anotherArray = array1; // Referenced array1 by another variable
array1.length = 0; // Empty the array by setting length to 0
console.log(anotherArray); // Output []
The line
array1 = [];
does not modify the array object previously assigned to array1
. It assigns a new (empty) array to the variable; it's not like invoking an operation on the object assigned to array1
.
To explain it in other words, assume array1
was the only variable referring the previously assigned array object ([1,2,3,4,5,6,7]
). Upon execution of that line (which is a statement, btw) you got lost of the previously assigned array; and it would be garbage collected some time later. This is all because the assignment operator is used here and they way its operational semantics is defined in JavaScript.
What is more, your are misusing the concept of pass by reference here (a.k.a. call by reference); which is a concept that relates to how values are passed to arguments of functions calls (or sub routines/procedures, if you prefer speaking of sub routines/procedures rather than functions).
In the assignment operator, a = x
, the right-hand side is evaluated as an expression (x
) and the resulting value is assigned to a
.
This implies that a
never “references” x
.
Thus both a = b
and a = []
result in a
being re-assigned. It is irrelevant if the right-hand side is a variable (that is evaluated) or an empty array literal:
var b = [1,2,3] // create and assign array #1
var a = b
// ^— a is assigned the result of evaluating b
// after this assignment a and b “refer to” (read: evaluate to) the same object..
// b -> [1,2,3] #1
// a -> [1,2,3] #1
a.pop()
// ^— modify array object (a.length = 0 would empty the array)
// ..and since a and b refer to THE SAME ARRAY..
// b -> [1,2] #1
// a -> [1,2] #1
var a = [] // create and assign array #2
// ^— a is assigned the result of evaluating []
// after re-assignment both a and b refer to different array objects..
// (the assignment did not alter mutate the original array)
// b -> [1,2] #1
// a -> [] #2
a.push(3)
// ^— modify array object
// ..and since a and b refer to DIFFERENT ARRAYS..
// b -> [1,2] #1
// a -> [3] #2
Calling functions works the exact same way as assignments and there is no “call by reference” in JavaScript. The values that result from the evaluation of expressions are supplied as arguments. JavaScript has Call by (Object) Sharing semantics.
tldr: there is no need to talk about “references” in Javascript here, as they add needless confusion and are not even defined (in this manner) in the specification!
In the first instance you're not actually updating the object that is referenced by array1.
You're replacing the value under the variable name array1
. anotherArray
is pointing to the value in memory that was the previous value held in array1
.
In the second example you're actually updating the underlying value that array1
and anotherArray
are both pointing to