Register to get access to free programming courses with interactive exercises

References JS: Arrays

Variables (and constants) in JavaScript can store two types of data: primitive and reference. Primitive types include numbers, strings, booleans, and so on. Objects are reference type data. The general idea of objects won't be studied until the next course, but an array is also an object:

typeof []; // 'object'

What is the difference between referential and primitive data types, and is it important to know?

From an application programmer's perspective, the difference is seen when data is changed, passed to, and returned from functions. We already know that an array can be changed even if it's written as a constant. This is where the referential nature comes into play. A constant stores a reference to an array, not the array itself, and this reference in and of itself does not change. But the array can change. This trick won't work with primitive types.

Another way to make sure that arrays are references is to create several constants containing the same array and see how they change:

const items = [1, 2];
// They refer to the same array
const items2 = items;
items2.push(3);

console.log(items2); // => [1, 2, 3]
console.log(items); // => [1, 2, 3]
items2 === items; // true

Comparison of arrays is also done by their reference. It may seem rather surprising if you're not used to it. Arrays with the same structure will have different references and are not equal to each other:

[1,2,3] === [1,2,3]; // false

Moreover, if you pass an array to a function that changes it, the reference will also change. After all, it's the reference to the array that is passed to the function. Have a look at this example:

const f = (coll) => coll.push('wow');

const items = ['one'];
f(items);
console.log(items); // => ['one', 'wow']
f(items);
console.log(items); // => ['one', 'wow', 'wow']

Designing functions

When designing functions that work with arrays, there are two ways it can be done. You can either change the original array or create a new array within and return that. Which one is better? In the vast majority of cases, the second option is preferred. It's safer. Functions that return new values are more convenient to use, and the behavior of the program becomes generally more predictable since there are no uncontrolled changes in the data.

Mutating an array can have unexpected effects. Imagine a last() function that retrieves the last element from an array. It could have been written like this:

// The .pop method retrieves the last element of the array
// It changes the array by removing this element
const last = (coll) => coll.pop();

When writing this code, all you really wanted to do was to view the last element. And in addition to that, the function designed to retrieve that item specifically removed said item from the array. This behavior is very unexpected for a feature like this. It contradicts many principles of good code construction (e.g., cqs, which is a principle that we'll look at in our course on functions). The correct implementation of this function is as follows:

const last = (coll) => coll[coll.length - 1]

When is it worth mutate the array itself? There's exactly one reason why they do it – for performance. This is why some built-in array methods actually mutate arrays, such as reverse() and sort():

const items = [3, 8, 1];

// The results aren't assigned to the constant; the array changes directly
items.sort();
console.log(items); // => [1, 3, 8]

items.reverse();
console.log(items); // => [8, 3, 1]

Usually, the documentation of each function underlines whether it modifies the original array or returns a new array without modifying the original one. For example, the concat() method, unlike sort(), returns a new array, something which is mentioned in the documentation.

Although the direct array-changing approach is more difficult to debug, it does get used in some languages to increase efficiency. If the array is large enough, creating a full copy may prove to be quite a bloated operation. In real life (as a web developer) this is almost never a problem, but it's useful to know about it.

For full access to the course you need a professional subscription.

A professional subscription will give you full access to all Hexlet courses, projects and lifetime access to the theory of lessons learned. You can cancel your subscription at any time.

Get access
130
courses
1000
exercises
2000+
hours of theory
3200
tests

Sign up

Programming courses for beginners and experienced developers. Start training for free

  • 130 courses, 2000+ hours of theory
  • 1000 practical tasks in a browser
  • 360 000 students
By sending this form, you agree to our Personal Policy and Service Conditions

Our graduates work in companies:

Bookmate
Health Samurai
Dualboot
ABBYY