An array is a reference
Picture a house and a slip of paper with its address. If you copy the address onto a second slip, there are still not two houses: both slips lead to one and the same house. If you follow the first slip and move the furniture, a guest with the second slip will see it in its new place too.
A number works differently: the assignment b = a copies the value itself. For an array, it works like the second slip: after b.push(3), the length of a has grown too. And two arrays with the same elements are not equal to each other:
const a = [1, 2];
const b = a;
b.push(3);
console.log(a.length); // 3
console.log(a === b); // true
console.log([1, 2] === [1, 2]); // falseLet's go through it line by line:
const a = [1, 2]creates an array, andapoints to it.const b = adoes not create a second array:bis a second name for the same array.b.push(3)adds an element to that one array.a.lengthprints3: the change made throughbshows througha.a === bgivestrue: both names point to one array.[1, 2] === [1, 2]givesfalse, even though the elements are the same.
Two names for one array
A variable holds not the array itself but a reference to it, a note of where the array lives. It is like a house address on a slip of paper: b = a copies the address, and there is still one house. Unlike an address, a reference cannot be seen or printed.
The assignment b = a copies the reference, and both names point to one and the same array. A change made through one name shows through the other. const does not help here: the constant holds the reference, not the array's contents.
An array is passed to a function the same way. The function's parameter gets a reference to the same array, so push inside the function changes the array outside. Interviewers often ask this: "What happens to an array if you change it inside a function?"
Press "Next step" and watch a and b: after every change they hold the same contents. The array c is a separate copy: its changes do not show through a. We will take apart the [...a] notation that makes the copy a little further down.
1function addItem(list, item) {2 list.push(item);3}4 5const a = [1, 2];6const b = a;7b.push(3);8console.log(a.length);9 10const c = [...a];11c.push(4);12console.log(a.length, c.length);13 14addItem(a, 5);15console.log(b.length);16console.log(a === b, a === c);
Writing [1, 2] creates an array, and a gets a reference to it.
Comparing arrays
For arrays, the === operator does not compare elements. It checks whether both sides are one and the same array, that is, whether the references are the same. Each [1, 2] creates a new array, so [1, 2] === [1, 2] gives false.
A copy with three dots
A separate copy is made by [...a]. Three dots before an array are called spread syntax: they spread the array out into separate elements. A slice() call with no arguments gives the same kind of copy.
const a = [3, 8, 1];
const copy = [...a];
copy.push(9);
console.log(a.length, copy.length); // 3 4
console.log(copy === a); // false
console.log([0, ...a].join(" ")); // 0 3 8 1
console.log(Math.max(...a)); // 8In a new array
In [...a] the elements go into a new array, and the copy has its own reference. That is why copy.push(9) does not change a, and copy === a gives false. Other elements can stand next to the three dots: [0, ...a] is 0 followed by all the elements of a.
In a function call
An array can also be spread with three dots in a function call. Math.max returns the largest of its arguments. The call Math.max(...a) passes three numbers as separate arguments, while Math.max(a) would get one array and return NaN.
Common mistake
An array is checked for emptiness by comparing it with []:
const list = [];
if (list === []) { // ✗
console.log("empty");
}There is no error, but the program prints nothing. To the right of === stands a new empty array, not list, and the condition is always false. Emptiness is checked by the length: list.length === 0.
Key points
- A variable holds a reference to an array, and
b = agives the same array a second name. - A function gets a reference to the same array and can change it.
===compares references, not elements, so[1, 2] === [1, 2]givesfalse.[...a]makes a separate copy of the array with a new reference.
Subscribe to take the course
The course is free. Sign in with Telegram and subscribe to the channel to open every lesson.