Introduction
We first got introduced to the concept of arrays all the way back in the JavaScript Data Types chapter. There, very briefly, we saw what exactly is an array; how to create one; how to add stuff to an array; how to sort elements; and much more.
Now all that information was brief, and only sufficient enough to give you head start on the array reference type.
Arrays in JavaScript are full of tons and tons of concepts and applications, some of which require very careful understanding. We have things like mutability, dimensions, sparse vs. dense arrays, dynamicity, instance checks and much more.
Arrays are an extremely elementary concept in JavaScript and programming, in general, knowing which will allow you to work more effectively in your programs and be able to implement many many common algorithms out there.
Let's dive into the learning.
What are arrays?
Let's start by reviewing what exactly is an array, before moving to explore the array of concepts related to arrays.
At the core level:
The idea of an array is quite similar to the idea of a string. A string is a sequence of textual characters while an array is a sequence of items.
An array could be thought of as a list of values. Let's say you were to store the list of numbers you obtained in recent exams, or the list of items to buy from the grocery store — in each case, what you'd need is an array.
Some people also define an array as an ordered collection of items. This is simply the definition of a sequence.
Anyways, moving on, as with all sequences, each item in a given array sits at a given position. This is referred to as its index. In programming, indexes typically begin at 0
.
Hence, the first item of an array is at index 0, the second one is at index 1, the third one is at index 2, and so on and so forth.
The total number of items in an array is referred to as the length of the array.
So if an array contains three items, its length would simply be equal to 3.
Alright, so with this basic theory in mind, let's now see how to create an array in JavaScript.
Array literals
Creating an array in JavaScript is as easy as creating a number, string, or Boolean — thanks to array literals.
A pair of square brackets []
is the literal way to denote an array. Inside the brackets, we put the individual elements of the array, separated by commas from other elements.
In general form, we could represent an array literal as follows:
[item1, item2, ..., itemN]
Each identifier — item1
, item2
, all the way up to itemN
— represents an item stored in the array.
Let's go on and create an array holding the three numbers 1, 2, and 3:
var nums = [1, 2, 3];
Easy, wasn't this?
Logging an array in the console gives a special result — there is a small arrow displayed before the array in the output.
Shown below is an example of logging the nums
array created above:

Notice the small ▸ arrow before the array?
Clicking this button shows the complete list of items in the array next to their respective indices, as follows:

Throughout this course, when representing arrays in the console, we'll just show the actual value without any arrows. Something like the following:
Coming back to the array nums
, let's add its starting two numbers and see the result. But wait...
For this, we'll need to access the first and second element of nums
.
How to do so?
To access an array element in JavaScript, we use what's called bracket notation. We begin with the array, followed by a pair of square brackets ([]
). Inside these, we put the index of the element desired to be accessed.
In general notation, this could be expressed as follows:
arr[index]
arr
is the array and index
is the index of the element wished to be retrieved.
Alright, now that we know how to access an array element, it's time to add the first two numbers of nums
. This is accomplished as follows:
var nums = [1, 2, 3];
console.log(nums[0] + nums[1]);
The first number has index 0
, hence we use nums[0]
to access it. Similarly, the second number is at index 1
, hence we use nums[1]
to access it.
nums[0]
evaluates to 1
and nums[1]
evaluates to 2
, hence nums[0] + nums[1]
is the same as 1 + 2
, which then evaluates down to 3
.
What if now we want to change the second number from 2
to 20
?
Can we do that in a JavaScript array?
A big yes!
To modify an exisiting array element, we use the same bracket notation we saw earlier above, but in the context of an assignment. That is, the bracket notation is followed by an equals sign (=
) followed by the new value to put at the desired index.
In general form, this could be expressed as:
arr[index] = newValue
arr
is the array, index
is the index of the element you wish to access and newValue
is the new value you want to put in the arr[index]
.
Let's see a quick modification example:
var nums = [1, 2, 3];
nums[1] = 20;
console.log(nums[1]);
As can be seen in the first log here, after executing nums[1] = 20
, the second item of nums
is no longer 2
— rather it is equal to the new value 20
.
Next, we add this number to the third number in nums
and see its return value.
nums[1] + nums[2]
As expected, it's 23
.
So at this point, we know how to create an array, put stuff in it and then later on change that stuff. A couple of things still left to be covered are how to add more elements to an array and remove given elements.
Adding stuff
There is more than just one way to add an element to an array. In this section, we'll cover the two most common ways — using bracket notation and push()
.
The rest of the ways are usually more specific to given applications. We'll discuss them in the next chapter.
Bracket notation
Many programming languages won't allow us to access an array index greater than or equal to the size of the array. For instance, in Python, doing so would throw an error of type IndexError
.
JavaScript is however, loosely-checked in many sectors — and array indices is one of these.
It's not invalid to access an array index that is greater than or equal to the array's length in JavaScript. In normal element access context, such an expression returns undefined
, while in the context of an assignment, it adds a new element at the specified position.
This means that to add an element to (the end of) an array, we could simply use something as follows:
arr[arr.length] = value;
arr.length
is 1 greater than the last index of arr
and so assigning a value to this index would add that value exactly at the end of arr
.
Shown below is an example:
var nums = [1, 2, 3];
nums[nums.length] = 10; // nums is now [1, 2, 3, 10]
nums[nums.length] = 20; // nums is now [1, 2, 3, 10, 20]
nums[nums.length] = 30; // nums is now [1, 2, 3, 10, 20, 30]
console.log(nums);
We start by creating an array nums
and then add three new items. Each item is added by assigning a value to the index nums.length
, which is next to the last element in the array.
Note that it's not required to use the expression arr.length
as the index to add a new element to arr
— if we know the last index of the array beforehand, we can even manually pass on the next index manually.
In the code below, we do the same thing as we did above except for that now we manually pass the new indices:
var nums = [1, 2, 3];
nums[3] = 10;
nums[4] = 20;
nums[5] = 30;
console.log(nums);
Moving on, if what you want is to add an element to the end of an array, then there is a simpler way than this one. It's to use the push()
array method.
push()
The push()
array method takes an argument and appends it to an array. Append simply means to add an item to the end of the array.
It's also possible to provide multiple arguments to push()
at once. In this case, they are all added one after another to the end of the array.
Syntactically, push()
could be shown as follows:
arr.push(item1[, item2 ... [, itemN]])
The best part of using push()
to add a new item to an array is that we don't need to specify an index manually — the method takes care of all the insertion logic itself.
In the code below, we create an array nums
and then add three numbers to it:
var nums = [1, 2, 3];
nums.push(10);
nums.push(20);
nums.push(30);
See how we don't have to care about giving indices of where to put the new elements at, when we use push()
.
Let's log each of the newly-added elements of nums
and see what do we get.
nums[3]
nums[4]
nums[5]
As expected, we get the same numbers returned that were appended to nums
.
Amazing!
Removing stuff
Often times while working with arrays, it's desired to remove items completely from it. This can be accomplished in a couple of ways depending on which element is wished to be removed.
pop()
To remove the last element from an array, we use the pop()
array method.
It requires no argument and when called, removes and returns the last element from the given array.
Here is its syntax:
arr.pop()
Note that after calling pop()
, the length of the array is changed and this is reflected in the length
property.
Let's create an array nums
and remove its last two elements one-by-one, meanwhile logging the removed element and the length
of the array after calling the pop()
method:
var nums = [1, 10, 50];
console.log('Removing:', nums.pop());
console.log('Length of nums:', nums.length);
console.log('\n');
console.log('Removing:', nums.pop());
console.log('Length of nums:', nums.length);
Length of nums: 2
Removing: 10
Length of nums: 1
In the first log statement, nums.pop()
removes 50
from nums
and consequently returns it. This return value is displayed in the console, followed by the current length of the array (after executing the pop()
method), which is now 2
.
Similarly in the last set of log statements, nums.pop()
removes 10
from nums
and returns it. As before, this return value is displayed in the console, followed by the current length of the array (after executing the pop()
method), which is now 1
.
shift()
The shift()
method is quite similar to pop()
in that it also removes a single element from a given array and takes no argument.
The main difference is the position at which it operates — shift()
removes the first element from an array and shifts all elements up by one position.
arr.shift()
Akin to pop()
, it modifies the length of the given array.
Below we create an array nums
and sequentially remove its first two elements, meanwhile logging the removed element and the new length of the array after the removal.
var nums = [1, 10, 50];
console.log('Removing:', nums.shift());
console.log('Length of nums:', nums.length);
console.log('\n');
console.log('Removing:', nums.shift());
console.log('Length of nums:', nums.length);
Length of nums: 2
Removing: 10
Length of nums: 1
One thing to keep in mind is that it involves shifting of all subsequence items, after the first item, down by one position. This shifting takes time — internally the engine iterates over each element and repositions it one step backwards.
If you want to remove all elements from an array one-by-one, it's generally better to use pop()
since it doesn't involve any shifting and is comparatively very efficient as compared to shift.
The Array()
constructor
As with most of the data types in JavaScript, there is a global function which we could use to create an array. It is Array()
.
Now whether we call it in the context of a constructor i.e. with the new
keyword, or in the context of a normal function, i.e. without new
, it doesn't matter. What's returned in both cases is an array object.
For instance,
Number()
returns the primitive value 0
, whereas new Number()
returns a Number
object wrapping the value 0
.The Array()
constructor has two distinct forms.
When it is called with a single argument of type number, a sparse array is created with that many empty holes (we'll explore sparse arrays later on in this chapter):
new Array([length])
The length
property of the array is set to the provided number argument. If the argument is a float, an error is thrown.
For instance, Array(5)
won't create the array [5]
, but rather an array whose length is 5
and that is filled with empty slots. These empty slots don't have any value at all, not even undefined
. They are totally blank!
We'll explore this type of invocation of Array()
later on below.
On the otherhand, when Array()
is called with multiple arguments, or with a single argument that is not a number, the arguments are taken to be elements of the array being created.
new Array([item1[, item2[, ...[, itemN]]]])
For instance, Array('2')
would return the array ['2']
, as the single argument provided to it is not a number. Similarly, Array(1, '2')
would return the array [1, '2']
, as it is called with multiple arguments (even though the first argument is a number).
There is nothing special about the return value of Array()
— it's the same array that we'd get using the array literal syntax.
In the code below, we create an array using the Array()
constructor and then process it:
var nums = new Array(1, 2, 3);
nums.push(10);
nums.push(20);
console.log(nums);
As you can see here, when an array is logged, it's displayed in the literal format, i.e. with the square brackets ([]
).
Alright, let's come back to the special case of Array()
, where there is only one argument specified.
Shown below is an actual demonstration:
var nums = Array(3);
console.log(nums);
Notice the log made. empty x 3
simply means that the array has 3 empty spaces in it.
Keep in mind these empty spaces are not undefined
, even though when we access any one element, we get undefined
returned as shown below:
var nums = Array(3);
console.log(nums[0]);
The reason why we get undefined
returned when accessing these empty spaces is because the JavaScript interpreter is configured to always return undefined
when accessing an undefined entity on a given value, such as when accessing a non-existent property on an object.
In this case, since the accessed index is empty, the interpreter returns undefined
. The underlying value is not actually undefined
.
JavaScript is undoubtedly very weird at times!
Now the question is that should you be using Array(n)
, where n
is an integer to predefine the number of elements an array would have?
Well, there isn't any significant benefit at all of using Array(n)
to preinitialise an array to a given length. Internally, JavaScript is completely different from how it looks on the front. What might seem like a valid optimisation may be just some redundant statement.
In short,
But there is one case where using the Array()
constructor could save you the time and space of creating an equivalent array using a loop. We'll see this case in the chapter JavaScript Array Methods.
Sparse arrays
Usually, the arrays we work with all the time in JavaScript have elements at contiguous positions. That is, there is no empty space before, after, or in between the elements; they come one after another.
Such arrays are commonly referred to as dense arrays.
Why 'dense'? Simply because all the elements are densely arranged one after another such that there is no empty space in between.
The opposite of dense arrays are sparse arrays.
In the previous sections, we showed two cases where the array obtained had holes in it.
Can you recall these two cases?
One is when we delete an array element using the delete
keyword. The second is when we create an array by calling the Array()
function with a single integer argument, like Array(3)
.
In both these cases, the array returned in the end has empty spaces in it. Elements are not jam-packed one after another — this is why we call these arrays sparse.
A sparse array's length would always be greater than the actual number of elements in it.
As an example consider the following code:
var nums = [1, 2, 3];
delete arr[1];
console.log(nums);
console.log(nums.length)
3
First we create an array nums
with three elements and then delete the second element from it using delete
. Now after this deletion, nums
has actually 2 elements left, but its length
property is still 3
.
This is a characteristic common to all sparse arrays — they have less elements than the shown length.
Huge sparse arrays
JavaScript engines are highly optimized to make intelligent decisions based on what's happening or will eventually happen in a given program. In the case of sparse arrays, there are optimizations and decisions involved as well.
As we saw above, calling Array()
with a single integer argument n
creates a sparse array. When the integer n
passed on to the function is quite large, which is figured out based on different heuristics, instead of creating an array of length n
with as many empty fields, the engine creates an object with a property length
set to n
and returns that.
The array is not implemented as a true array in memory, but rather as an object where indices are merely keys. The object behaves similar to how a native JavaScript object, like {x: 10, y: 10}
, would do.
This means that element-access expressions, such as arr[100]
won't be as quick as with native arrays — they would be accessing the respective property on the array-like object, which would have to be searched for in the object and its prototypal chain.
In performance-intensive applications, this could cause memory problems as well as prolong the running times of element-access expressions.
Following from this behavior, it's generally recommended to avoid using Array(n)
to create large arrays, and also to avoid creating sparse arrays whenever possible.
Mutability
Back in the JavaScript String Basics chapter, we learnt that string in JavaScript are immutable in nature i.e once created they couldn't be changed.
Consider the code below where this idea could be seen:
var str = 'Good';
str[0] = 'F';
console.log(str)
In the second statement, we aim to change the first character of the string str
to 'F'
, and then log str
to the console. The log is 'Good'
instead of the expected value 'Food'
— the string str
wasn't changed. The assignment statement was just ignored.
The reason why the code above logs 'Good'
instead of 'Food'
is because, in JavaScript, strings are immutable and hence couldn't be modified once created. The only way to change the text within a string is to create a new string with the new piece of text.
The opposite concept to this is that of mutability.
In JavaScript, arrays are mutable in nature. That is, we can change — or better to say, mutate — them once created.
The classic example to demonstrate the mutability of arrays is shown as follows:
var nums = [1, 2, 3];
nums[1] = 10;
console.log(nums);
We create an array nums
with a couple of elements and then change its second element. After this, we log the array to see if the modification was considered or simply ignored (as in the case of strings).
The log made clearly shows that indeed the modification was considered and that the original array nums
was changed. This confirms that, yes, arrays are mutable.
Dimensions
In all of the examples of arrays you have seen uptil now how many times did we need to specify an index? Once? Yes, absolutely and therefore all those arrays can be called single dimension arrays.
Recall the fact that array elements can be of any type in JavaScript - and arrays are no exception!
When we have arrays as array elements we have a multi-dimension array. More specifically the array can be two dimensional (2D), three dimensional (3D), and even further than that.
Take a look at the code below:
var arr = [[1, 2], [5, 3]]; // a 2d array
The array arr
has two elements - both arrays themselves.
If we want to access the number 1
in the code above, we need to first refer to the first element of arr
, and then to the first element of this selected array.
The following snippet logs all the four numbers in the code above:
console.log(arr[0][0]); // 1
console.log(arr[0][1]); // 2
console.log(arr[1][0]); // 5
console.log(arr[0][1]); // 3
When we write arr[0][1]
, arr[0]
returns the first element of arr
, and since this element is itself an array, we can further fetch elements by using the same notation.
The part [1]
, after arr[0]
, fetches the second element out of the array arr[0]
which is [1, 2]
, and consequently returns 2
.
Such simple!
Checking for arrays
In JavaScript, it's possible to check whether a given value is an array, but at least not using the typeof
operator. Can you recall why, back from the JavaScript Data Types chapter?
Well the answer is simple — because the operator returns 'object'
even for arrays!
var arr = [1, 2];
console.log(typeof arr);
So how can we check for an array?
Well there are a couple of ways:
The instanceof
operator
The simplest way to check whether a given value is an array or not is to use the instanceof
operator.
Here's its syntax to check for an array:
value instanceof Array
If value
is an array, this expression would return true
; otherwise it would return false
.
Let's try using instanceof
on a couple of values:
[] instanceof Array
[1, 2, 3] instanceof Array
null instanceof Array
true instanceof Array
{0: 1, 1: 2} instanceof Array
In the first two cases, since the given value is an array, we get true
returned. In all other cases, since the given values are not arrays, false
is returned.
The best part about using instanceof
is that it is very well supported an older browsers.
However, there is one case where instanceof
doesn't work as expected. It's detailed below.
In an iframe, if you want to check whether an outsider value is an array, the following code won't work as expected:
// this is code inside an iframe
// outsideArray is obtained from the outside window
console.log(outsideArray instanceof Array);
The reason is because the outsider value is based on the Array
object type in its own execution context, NOT on the Array
object is another window's execution context. You'll learn more about this in the JavaScript Objects unit.
The instanceof
operator
The idea behind the name instanceof
comes from the fact that it checks whether an object is an instance of a given class. An instance is simply an object belonging to a given class. We'll learn more about instances and objects in the JavaScript Objects unit.
The Array.isArray()
method
The second way to check whether a given value is an array is to use the isArray()
method on the global Array
object.
Syntactically, it could be shown as follows:
Array.isArray(value)
It returns true
when the value
argument is an array, and false
otherwise.
Consider the following snippet:
Array.isArray([])
Array.isArray([1, 2, 3])
Array.isArray(null)
Array.isArray(true)
Array.isArray({0: 1, 1: 2})
The return value for each statement here is the same as that using the instanceof
operator, as we saw above.
Unlike instanceof
, Array.isArray()
can also solve the outer-window array check problem we saw above.
// this is code inside an iframe
// outsideArray is obtained from the outside window
console.log(Array.isArray(outsideArray));