Which of the following method call gives the position of X that occurs after?

That’s natural, because

let arr = ["I", "study", "JavaScript"];

// from index 2
// delete 0
// then insert "complex" and "language"
arr.splice(2, 0, "complex", "language");

alert( arr ); // "I", "study", "complex", "language", "JavaScript"
3 removes a value by the
let arr = ["I", "study", "JavaScript"];

// from index 2
// delete 0
// then insert "complex" and "language"
arr.splice(2, 0, "complex", "language");

alert( arr ); // "I", "study", "complex", "language", "JavaScript"
4. It’s all it does. Fine for objects. But for arrays we usually want the rest of elements to shift and occupy the freed place. We expect to have a shorter array now.

So, special methods should be used.

The arr.splice method is a swiss army knife for arrays. It can do everything: insert, remove and replace elements.

The syntax is:

arr.splice(start[, deleteCount, elem1, ..., elemN])

It modifies

let arr = ["I", "study", "JavaScript"];

// from index 2
// delete 0
// then insert "complex" and "language"
arr.splice(2, 0, "complex", "language");

alert( arr ); // "I", "study", "complex", "language", "JavaScript"
5 starting from the index
let arr = ["I", "study", "JavaScript"];

// from index 2
// delete 0
// then insert "complex" and "language"
arr.splice(2, 0, "complex", "language");

alert( arr ); // "I", "study", "complex", "language", "JavaScript"
6: removes
let arr = ["I", "study", "JavaScript"];

// from index 2
// delete 0
// then insert "complex" and "language"
arr.splice(2, 0, "complex", "language");

alert( arr ); // "I", "study", "complex", "language", "JavaScript"
7 elements and then inserts
let arr = ["I", "study", "JavaScript"];

// from index 2
// delete 0
// then insert "complex" and "language"
arr.splice(2, 0, "complex", "language");

alert( arr ); // "I", "study", "complex", "language", "JavaScript"
8 at their place. Returns the array of removed elements.

This method is easy to grasp by examples.

Let’s start with the deletion:

let arr = ["I", "study", "JavaScript"];

arr.splice(1, 1); // from index 1 remove 1 element

alert( arr ); // ["I", "JavaScript"]

Easy, right? Starting from the index

let arr = ["I", "study", "JavaScript"];

// from index 2
// delete 0
// then insert "complex" and "language"
arr.splice(2, 0, "complex", "language");

alert( arr ); // "I", "study", "complex", "language", "JavaScript"
9 it removed
let arr = ["I", "study", "JavaScript"];

// from index 2
// delete 0
// then insert "complex" and "language"
arr.splice(2, 0, "complex", "language");

alert( arr ); // "I", "study", "complex", "language", "JavaScript"
9 element.

In the next example we remove 3 elements and replace them with the other two:

let arr = ["I", "study", "JavaScript", "right", "now"];

// remove 3 first elements and replace them with another
arr.splice(0, 3, "Let's", "dance");

alert( arr ) // now ["Let's", "dance", "right", "now"]

Here we can see that

let arr = [1, 2, 5];

// from index -1 (one step from the end)
// delete 0 elements,
// then insert 3 and 4
arr.splice(-1, 0, 3, 4);

alert( arr ); // 1,2,3,4,5
1 returns the array of removed elements:

let arr = ["I", "study", "JavaScript", "right", "now"];

// remove 2 first elements
let removed = arr.splice(0, 2);

alert( removed ); // "I", "study" <-- array of removed elements

The

let arr = [1, 2, 5];

// from index -1 (one step from the end)
// delete 0 elements,
// then insert 3 and 4
arr.splice(-1, 0, 3, 4);

alert( arr ); // 1,2,3,4,5
1 method is also able to insert the elements without any removals. For that we need to set
let arr = ["I", "study", "JavaScript"];

// from index 2
// delete 0
// then insert "complex" and "language"
arr.splice(2, 0, "complex", "language");

alert( arr ); // "I", "study", "complex", "language", "JavaScript"
7 to
let arr = [1, 2, 5];

// from index -1 (one step from the end)
// delete 0 elements,
// then insert 3 and 4
arr.splice(-1, 0, 3, 4);

alert( arr ); // 1,2,3,4,5
4:

let arr = ["I", "study", "JavaScript"];

// from index 2
// delete 0
// then insert "complex" and "language"
arr.splice(2, 0, "complex", "language");

alert( arr ); // "I", "study", "complex", "language", "JavaScript"

Negative indexes allowed

Here and in other array methods, negative indexes are allowed. They specify the position from the end of the array, like here:

let arr = [1, 2, 5];

// from index -1 (one step from the end)
// delete 0 elements,
// then insert 3 and 4
arr.splice(-1, 0, 3, 4);

alert( arr ); // 1,2,3,4,5

slice

The method arr.slice is much simpler than similar-looking

let arr = [1, 2, 5];

// from index -1 (one step from the end)
// delete 0 elements,
// then insert 3 and 4
arr.splice(-1, 0, 3, 4);

alert( arr ); // 1,2,3,4,5
5.

The syntax is:

arr.slice([start], [end])

It returns a new array copying to it all items from index

let arr = ["I", "study", "JavaScript"];

// from index 2
// delete 0
// then insert "complex" and "language"
arr.splice(2, 0, "complex", "language");

alert( arr ); // "I", "study", "complex", "language", "JavaScript"
6 to
let arr = [1, 2, 5];

// from index -1 (one step from the end)
// delete 0 elements,
// then insert 3 and 4
arr.splice(-1, 0, 3, 4);

alert( arr ); // 1,2,3,4,5
7 (not including
let arr = [1, 2, 5];

// from index -1 (one step from the end)
// delete 0 elements,
// then insert 3 and 4
arr.splice(-1, 0, 3, 4);

alert( arr ); // 1,2,3,4,5
7). Both
let arr = ["I", "study", "JavaScript"];

// from index 2
// delete 0
// then insert "complex" and "language"
arr.splice(2, 0, "complex", "language");

alert( arr ); // "I", "study", "complex", "language", "JavaScript"
6 and
let arr = [1, 2, 5];

// from index -1 (one step from the end)
// delete 0 elements,
// then insert 3 and 4
arr.splice(-1, 0, 3, 4);

alert( arr ); // 1,2,3,4,5
7 can be negative, in that case position from array end is assumed.

It’s similar to a string method

arr.slice([start], [end])
1, but instead of substrings it makes subarrays.

For instance:

let arr = ["t", "e", "s", "t"];

alert( arr.slice(1, 3) ); // e,s (copy from 1 to 3)

alert( arr.slice(-2) ); // s,t (copy from -2 till the end)

We can also call it without arguments:

arr.slice([start], [end])
2 creates a copy of
let arr = ["I", "study", "JavaScript"];

// from index 2
// delete 0
// then insert "complex" and "language"
arr.splice(2, 0, "complex", "language");

alert( arr ); // "I", "study", "complex", "language", "JavaScript"
5. That’s often used to obtain a copy for further transformations that should not affect the original array.

concat

The method arr.concat creates a new array that includes values from other arrays and additional items.

The syntax is:

arr.concat(arg1, arg2...)

It accepts any number of arguments – either arrays or values.

The result is a new array containing items from

let arr = ["I", "study", "JavaScript"];

// from index 2
// delete 0
// then insert "complex" and "language"
arr.splice(2, 0, "complex", "language");

alert( arr ); // "I", "study", "complex", "language", "JavaScript"
5, then
arr.slice([start], [end])
5,
arr.slice([start], [end])
6 etc.

If an argument

arr.slice([start], [end])
7 is an array, then all its elements are copied. Otherwise, the argument itself is copied.

For instance:

arr.splice(start[, deleteCount, elem1, ..., elemN])
0

Normally, it only copies elements from arrays. Other objects, even if they look like arrays, are added as a whole:

arr.splice(start[, deleteCount, elem1, ..., elemN])
1

…But if an array-like object has a special

arr.slice([start], [end])
8 property, then it’s treated as an array by
arr.slice([start], [end])
9: its elements are added instead:

arr.splice(start[, deleteCount, elem1, ..., elemN])
2

Iterate: forEach

The arr.forEach method allows to run a function for every element of the array.

The syntax:

arr.splice(start[, deleteCount, elem1, ..., elemN])
3

For instance, this shows each element of the array:

arr.splice(start[, deleteCount, elem1, ..., elemN])
4

And this code is more elaborate about their positions in the target array:

arr.splice(start[, deleteCount, elem1, ..., elemN])
5

The result of the function (if it returns any) is thrown away and ignored.

Searching in array

Now let’s cover methods that search in an array.

indexOf/lastIndexOf and includes

The methods arr.indexOf and arr.includes have the similar syntax and do essentially the same as their string counterparts, but operate on items instead of characters:

  • let arr = ["t", "e", "s", "t"];
    
    alert( arr.slice(1, 3) ); // e,s (copy from 1 to 3)
    
    alert( arr.slice(-2) ); // s,t (copy from -2 till the end)
    0 – looks for
    let arr = ["t", "e", "s", "t"];
    
    alert( arr.slice(1, 3) ); // e,s (copy from 1 to 3)
    
    alert( arr.slice(-2) ); // s,t (copy from -2 till the end)
    1 starting from index
    let arr = ["t", "e", "s", "t"];
    
    alert( arr.slice(1, 3) ); // e,s (copy from 1 to 3)
    
    alert( arr.slice(-2) ); // s,t (copy from -2 till the end)
    2, and returns the index where it was found, otherwise
    let arr = ["t", "e", "s", "t"];
    
    alert( arr.slice(1, 3) ); // e,s (copy from 1 to 3)
    
    alert( arr.slice(-2) ); // s,t (copy from -2 till the end)
    3.
  • let arr = ["t", "e", "s", "t"];
    
    alert( arr.slice(1, 3) ); // e,s (copy from 1 to 3)
    
    alert( arr.slice(-2) ); // s,t (copy from -2 till the end)
    4 – looks for
    let arr = ["t", "e", "s", "t"];
    
    alert( arr.slice(1, 3) ); // e,s (copy from 1 to 3)
    
    alert( arr.slice(-2) ); // s,t (copy from -2 till the end)
    1 starting from index
    let arr = ["t", "e", "s", "t"];
    
    alert( arr.slice(1, 3) ); // e,s (copy from 1 to 3)
    
    alert( arr.slice(-2) ); // s,t (copy from -2 till the end)
    2, returns
    let arr = ["t", "e", "s", "t"];
    
    alert( arr.slice(1, 3) ); // e,s (copy from 1 to 3)
    
    alert( arr.slice(-2) ); // s,t (copy from -2 till the end)
    7 if found.

Usually these methods are used with only one argument: the

let arr = ["t", "e", "s", "t"];

alert( arr.slice(1, 3) ); // e,s (copy from 1 to 3)

alert( arr.slice(-2) ); // s,t (copy from -2 till the end)
1 to search. By default, the search is from the beginning.

For instance:

arr.splice(start[, deleteCount, elem1, ..., elemN])
6

Please note that

let arr = ["t", "e", "s", "t"];

alert( arr.slice(1, 3) ); // e,s (copy from 1 to 3)

alert( arr.slice(-2) ); // s,t (copy from -2 till the end)
9 uses the strict equality
arr.concat(arg1, arg2...)
0 for comparison. So, if we look for
arr.concat(arg1, arg2...)
1, it finds exactly
arr.concat(arg1, arg2...)
1 and not the zero.

If we want to check if

let arr = ["t", "e", "s", "t"];

alert( arr.slice(1, 3) ); // e,s (copy from 1 to 3)

alert( arr.slice(-2) ); // s,t (copy from -2 till the end)
1 exists in the array, and don’t need the index, then
arr.concat(arg1, arg2...)
4 is preferred.

The method arr.lastIndexOf is the same as

let arr = ["t", "e", "s", "t"];

alert( arr.slice(1, 3) ); // e,s (copy from 1 to 3)

alert( arr.slice(-2) ); // s,t (copy from -2 till the end)
9, but looks for from right to left.

arr.splice(start[, deleteCount, elem1, ..., elemN])
7

The

arr.concat(arg1, arg2...)
6 method handles
arr.concat(arg1, arg2...)
7 correctly

A minor, but noteworthy feature of

arr.concat(arg1, arg2...)
6 is that it correctly handles
arr.concat(arg1, arg2...)
7, unlike
let arr = ["t", "e", "s", "t"];

alert( arr.slice(1, 3) ); // e,s (copy from 1 to 3)

alert( arr.slice(-2) ); // s,t (copy from -2 till the end)
9:

arr.splice(start[, deleteCount, elem1, ..., elemN])
8

That’s because

arr.concat(arg1, arg2...)
6 was added to JavaScript much later and uses the more up to date comparison algorithm internally.

find and findIndex/findLastIndex

Imagine we have an array of objects. How do we find an object with the specific condition?

Here the arr.find(fn) method comes in handy.

The syntax is:

arr.splice(start[, deleteCount, elem1, ..., elemN])
9

The function is called for elements of the array, one after another:

  • let arr = ["t", "e", "s", "t"];
    
    alert( arr.slice(1, 3) ); // e,s (copy from 1 to 3)
    
    alert( arr.slice(-2) ); // s,t (copy from -2 till the end)
    1 is the element.
  • arr.splice(start[, deleteCount, elem1, ..., elemN])
    03 is its index.
  • arr.splice(start[, deleteCount, elem1, ..., elemN])
    04 is the array itself.

If it returns

let arr = ["t", "e", "s", "t"];

alert( arr.slice(1, 3) ); // e,s (copy from 1 to 3)

alert( arr.slice(-2) ); // s,t (copy from -2 till the end)
7, the search is stopped, the
let arr = ["t", "e", "s", "t"];

alert( arr.slice(1, 3) ); // e,s (copy from 1 to 3)

alert( arr.slice(-2) ); // s,t (copy from -2 till the end)
1 is returned. If nothing found,
arr.splice(start[, deleteCount, elem1, ..., elemN])
07 is returned.

For example, we have an array of users, each with the fields

arr.splice(start[, deleteCount, elem1, ..., elemN])
08 and
arr.splice(start[, deleteCount, elem1, ..., elemN])
09. Let’s find the one with
arr.splice(start[, deleteCount, elem1, ..., elemN])
10:

let arr = ["I", "study", "JavaScript"];

arr.splice(1, 1); // from index 1 remove 1 element

alert( arr ); // ["I", "JavaScript"]
0

In real life arrays of objects is a common thing, so the

arr.splice(start[, deleteCount, elem1, ..., elemN])
11 method is very useful.

Note that in the example we provide to

arr.splice(start[, deleteCount, elem1, ..., elemN])
11 the function
arr.splice(start[, deleteCount, elem1, ..., elemN])
13 with one argument. That’s typical, other arguments of this function are rarely used.

The arr.findIndex method has the same syntax, but returns the index where the element was found instead of the element itself. The value of

let arr = ["t", "e", "s", "t"];

alert( arr.slice(1, 3) ); // e,s (copy from 1 to 3)

alert( arr.slice(-2) ); // s,t (copy from -2 till the end)
3 is returned if nothing is found.

The arr.findLastIndex method is like

arr.splice(start[, deleteCount, elem1, ..., elemN])
15, but searches from right to left, similar to
arr.splice(start[, deleteCount, elem1, ..., elemN])
16.

Here’s an example:

let arr = ["I", "study", "JavaScript"];

arr.splice(1, 1); // from index 1 remove 1 element

alert( arr ); // ["I", "JavaScript"]
1

filter

The

arr.splice(start[, deleteCount, elem1, ..., elemN])
11 method looks for a single (first) element that makes the function return
let arr = ["t", "e", "s", "t"];

alert( arr.slice(1, 3) ); // e,s (copy from 1 to 3)

alert( arr.slice(-2) ); // s,t (copy from -2 till the end)
7.

If there may be many, we can use arr.filter(fn).

The syntax is similar to

arr.splice(start[, deleteCount, elem1, ..., elemN])
11, but
arr.splice(start[, deleteCount, elem1, ..., elemN])
20 returns an array of all matching elements:

let arr = ["I", "study", "JavaScript"];

arr.splice(1, 1); // from index 1 remove 1 element

alert( arr ); // ["I", "JavaScript"]
2

For instance:

let arr = ["I", "study", "JavaScript"];

arr.splice(1, 1); // from index 1 remove 1 element

alert( arr ); // ["I", "JavaScript"]
3

Transform an array

Let’s move on to methods that transform and reorder an array.

map

The arr.map method is one of the most useful and often used.

It calls the function for each element of the array and returns the array of results.

The syntax is:

let arr = ["I", "study", "JavaScript"];

arr.splice(1, 1); // from index 1 remove 1 element

alert( arr ); // ["I", "JavaScript"]
4

For instance, here we transform each element into its length:

let arr = ["I", "study", "JavaScript"];

arr.splice(1, 1); // from index 1 remove 1 element

alert( arr ); // ["I", "JavaScript"]
5

sort(fn)

The call to arr.sort() sorts the array in place, changing its element order.

It also returns the sorted array, but the returned value is usually ignored, as

let arr = ["I", "study", "JavaScript"];

// from index 2
// delete 0
// then insert "complex" and "language"
arr.splice(2, 0, "complex", "language");

alert( arr ); // "I", "study", "complex", "language", "JavaScript"
5 itself is modified.

For instance:

let arr = ["I", "study", "JavaScript"];

arr.splice(1, 1); // from index 1 remove 1 element

alert( arr ); // ["I", "JavaScript"]
6

Did you notice anything strange in the outcome?

The order became

arr.splice(start[, deleteCount, elem1, ..., elemN])
22. Incorrect. But why?

The items are sorted as strings by default.

Literally, all elements are converted to strings for comparisons. For strings, lexicographic ordering is applied and indeed

arr.splice(start[, deleteCount, elem1, ..., elemN])
23.

To use our own sorting order, we need to supply a function as the argument of

arr.splice(start[, deleteCount, elem1, ..., elemN])
24.

The function should compare two arbitrary values and return:

let arr = ["I", "study", "JavaScript"];

arr.splice(1, 1); // from index 1 remove 1 element

alert( arr ); // ["I", "JavaScript"]
7

For instance, to sort as numbers:

let arr = ["I", "study", "JavaScript"];

arr.splice(1, 1); // from index 1 remove 1 element

alert( arr ); // ["I", "JavaScript"]
8

Now it works as intended.

Let’s step aside and think what’s happening. The

let arr = ["I", "study", "JavaScript"];

// from index 2
// delete 0
// then insert "complex" and "language"
arr.splice(2, 0, "complex", "language");

alert( arr ); // "I", "study", "complex", "language", "JavaScript"
5 can be array of anything, right? It may contain numbers or strings or objects or whatever. We have a set of some items. To sort it, we need an ordering function that knows how to compare its elements. The default is a string order.

The

arr.splice(start[, deleteCount, elem1, ..., elemN])
26 method implements a generic sorting algorithm. We don’t need to care how it internally works (an optimized quicksort or Timsort most of the time). It will walk the array, compare its elements using the provided function and reorder them, all we need is to provide the
arr.splice(start[, deleteCount, elem1, ..., elemN])
27 which does the comparison.

By the way, if we ever want to know which elements are compared – nothing prevents from alerting them:

let arr = ["I", "study", "JavaScript"];

arr.splice(1, 1); // from index 1 remove 1 element

alert( arr ); // ["I", "JavaScript"]
9

The algorithm may compare an element with multiple others in the process, but it tries to make as few comparisons as possible.

A comparison function may return any number

Actually, a comparison function is only required to return a positive number to say “greater” and a negative number to say “less”.

That allows to write shorter functions:

let arr = ["I", "study", "JavaScript", "right", "now"];

// remove 3 first elements and replace them with another
arr.splice(0, 3, "Let's", "dance");

alert( arr ) // now ["Let's", "dance", "right", "now"]
0

Arrow functions for the best

Remember arrow functions? We can use them here for neater sorting:

let arr = ["I", "study", "JavaScript", "right", "now"];

// remove 3 first elements and replace them with another
arr.splice(0, 3, "Let's", "dance");

alert( arr ) // now ["Let's", "dance", "right", "now"]
1

This works exactly the same as the longer version above.

Use

arr.splice(start[, deleteCount, elem1, ..., elemN])
28 for strings

Remember strings comparison algorithm? It compares letters by their codes by default.

For many alphabets, it’s better to use

arr.splice(start[, deleteCount, elem1, ..., elemN])
29 method to correctly sort letters, such as
arr.splice(start[, deleteCount, elem1, ..., elemN])
30.

For example, let’s sort a few countries in German:

let arr = ["I", "study", "JavaScript", "right", "now"];

// remove 3 first elements and replace them with another
arr.splice(0, 3, "Let's", "dance");

alert( arr ) // now ["Let's", "dance", "right", "now"]
2

reverse

The method arr.reverse reverses the order of elements in

let arr = ["I", "study", "JavaScript"];

// from index 2
// delete 0
// then insert "complex" and "language"
arr.splice(2, 0, "complex", "language");

alert( arr ); // "I", "study", "complex", "language", "JavaScript"
5.

For instance:

let arr = ["I", "study", "JavaScript", "right", "now"];

// remove 3 first elements and replace them with another
arr.splice(0, 3, "Let's", "dance");

alert( arr ) // now ["Let's", "dance", "right", "now"]
3

It also returns the array

let arr = ["I", "study", "JavaScript"];

// from index 2
// delete 0
// then insert "complex" and "language"
arr.splice(2, 0, "complex", "language");

alert( arr ); // "I", "study", "complex", "language", "JavaScript"
5 after the reversal.

split and join

Here’s the situation from real life. We are writing a messaging app, and the person enters the comma-delimited list of receivers:

arr.splice(start[, deleteCount, elem1, ..., elemN])
33. But for us an array of names would be much more comfortable than a single string. How to get it?

The str.split(delim) method does exactly that. It splits the string into an array by the given delimiter

arr.splice(start[, deleteCount, elem1, ..., elemN])
34.

In the example below, we split by a comma followed by space:

let arr = ["I", "study", "JavaScript", "right", "now"];

// remove 3 first elements and replace them with another
arr.splice(0, 3, "Let's", "dance");

alert( arr ) // now ["Let's", "dance", "right", "now"]
4

The

arr.splice(start[, deleteCount, elem1, ..., elemN])
35 method has an optional second numeric argument – a limit on the array length. If it is provided, then the extra elements are ignored. In practice it is rarely used though:

let arr = ["I", "study", "JavaScript", "right", "now"];

// remove 3 first elements and replace them with another
arr.splice(0, 3, "Let's", "dance");

alert( arr ) // now ["Let's", "dance", "right", "now"]
5

Split into letters

The call to

arr.splice(start[, deleteCount, elem1, ..., elemN])
36 with an empty
arr.splice(start[, deleteCount, elem1, ..., elemN])
37 would split the string into an array of letters:

let arr = ["I", "study", "JavaScript", "right", "now"];

// remove 3 first elements and replace them with another
arr.splice(0, 3, "Let's", "dance");

alert( arr ) // now ["Let's", "dance", "right", "now"]
6

The call arr.join(glue) does the reverse to

arr.splice(start[, deleteCount, elem1, ..., elemN])
35. It creates a string of
let arr = ["I", "study", "JavaScript"];

// from index 2
// delete 0
// then insert "complex" and "language"
arr.splice(2, 0, "complex", "language");

alert( arr ); // "I", "study", "complex", "language", "JavaScript"
5 items joined by
arr.splice(start[, deleteCount, elem1, ..., elemN])
40 between them.

For instance:

let arr = ["I", "study", "JavaScript", "right", "now"];

// remove 3 first elements and replace them with another
arr.splice(0, 3, "Let's", "dance");

alert( arr ) // now ["Let's", "dance", "right", "now"]
7

reduce/reduceRight

When we need to iterate over an array – we can use

arr.splice(start[, deleteCount, elem1, ..., elemN])
41,
arr.splice(start[, deleteCount, elem1, ..., elemN])
42 or
arr.splice(start[, deleteCount, elem1, ..., elemN])
43.

When we need to iterate and return the data for each element – we can use

arr.splice(start[, deleteCount, elem1, ..., elemN])
44.

The methods arr.reduce and arr.reduceRight also belong to that breed, but are a little bit more intricate. They are used to calculate a single value based on the array.

The syntax is:

let arr = ["I", "study", "JavaScript", "right", "now"];

// remove 3 first elements and replace them with another
arr.splice(0, 3, "Let's", "dance");

alert( arr ) // now ["Let's", "dance", "right", "now"]
8

The function is applied to all array elements one after another and “carries on” its result to the next call.

Arguments:

  • arr.splice(start[, deleteCount, elem1, ..., elemN])
    45 – is the result of the previous function call, equals
    arr.splice(start[, deleteCount, elem1, ..., elemN])
    46 the first time (if
    arr.splice(start[, deleteCount, elem1, ..., elemN])
    46 is provided).
  • let arr = ["t", "e", "s", "t"];
    
    alert( arr.slice(1, 3) ); // e,s (copy from 1 to 3)
    
    alert( arr.slice(-2) ); // s,t (copy from -2 till the end)
    1 – is the current array item.
  • arr.splice(start[, deleteCount, elem1, ..., elemN])
    03 – is its position.
  • arr.splice(start[, deleteCount, elem1, ..., elemN])
    04 – is the array.

As function is applied, the result of the previous function call is passed to the next one as the first argument.

So, the first argument is essentially the accumulator that stores the combined result of all previous executions. And at the end it becomes the result of

arr.splice(start[, deleteCount, elem1, ..., elemN])
51.

Sounds complicated?

The easiest way to grasp that is by example.

Here we get a sum of an array in one line:

let arr = ["I", "study", "JavaScript", "right", "now"];

// remove 3 first elements and replace them with another
arr.splice(0, 3, "Let's", "dance");

alert( arr ) // now ["Let's", "dance", "right", "now"]
9

The function passed to

arr.splice(start[, deleteCount, elem1, ..., elemN])
51 uses only 2 arguments, that’s typically enough.

Let’s see the details of what’s going on.

  1. On the first run,
    arr.splice(start[, deleteCount, elem1, ..., elemN])
    53 is the
    arr.splice(start[, deleteCount, elem1, ..., elemN])
    46 value (the last argument of
    arr.splice(start[, deleteCount, elem1, ..., elemN])
    51), equals
    let arr = [1, 2, 5];
    
    // from index -1 (one step from the end)
    // delete 0 elements,
    // then insert 3 and 4
    arr.splice(-1, 0, 3, 4);
    
    alert( arr ); // 1,2,3,4,5
    4, and
    arr.splice(start[, deleteCount, elem1, ..., elemN])
    57 is the first array element, equals
    let arr = ["I", "study", "JavaScript"];
    
    // from index 2
    // delete 0
    // then insert "complex" and "language"
    arr.splice(2, 0, "complex", "language");
    
    alert( arr ); // "I", "study", "complex", "language", "JavaScript"
    9. So the function result is
    let arr = ["I", "study", "JavaScript"];
    
    // from index 2
    // delete 0
    // then insert "complex" and "language"
    arr.splice(2, 0, "complex", "language");
    
    alert( arr ); // "I", "study", "complex", "language", "JavaScript"
    9.
  2. On the second run,
    arr.splice(start[, deleteCount, elem1, ..., elemN])
    60, we add the second array element (
    arr.splice(start[, deleteCount, elem1, ..., elemN])
    61) to it and return.
  3. On the 3rd run,
    arr.splice(start[, deleteCount, elem1, ..., elemN])
    62 and we add one more element to it, and so on…

The calculation flow:

Which of the following method call gives the position of X that occurs after?

Or in the form of a table, where each row represents a function call on the next array element:

arr.splice(start[, deleteCount, elem1, ..., elemN])
53
arr.splice(start[, deleteCount, elem1, ..., elemN])
57resultthe first call
let arr = [1, 2, 5];

// from index -1 (one step from the end)
// delete 0 elements,
// then insert 3 and 4
arr.splice(-1, 0, 3, 4);

alert( arr ); // 1,2,3,4,5
4
let arr = ["I", "study", "JavaScript"];

// from index 2
// delete 0
// then insert "complex" and "language"
arr.splice(2, 0, "complex", "language");

alert( arr ); // "I", "study", "complex", "language", "JavaScript"
9
let arr = ["I", "study", "JavaScript"];

// from index 2
// delete 0
// then insert "complex" and "language"
arr.splice(2, 0, "complex", "language");

alert( arr ); // "I", "study", "complex", "language", "JavaScript"
9the second call
let arr = ["I", "study", "JavaScript"];

// from index 2
// delete 0
// then insert "complex" and "language"
arr.splice(2, 0, "complex", "language");

alert( arr ); // "I", "study", "complex", "language", "JavaScript"
9
arr.splice(start[, deleteCount, elem1, ..., elemN])
61
arr.splice(start[, deleteCount, elem1, ..., elemN])
70the third call
arr.splice(start[, deleteCount, elem1, ..., elemN])
70
arr.splice(start[, deleteCount, elem1, ..., elemN])
70
arr.splice(start[, deleteCount, elem1, ..., elemN])
73the fourth call
arr.splice(start[, deleteCount, elem1, ..., elemN])
73
arr.splice(start[, deleteCount, elem1, ..., elemN])
75
arr.splice(start[, deleteCount, elem1, ..., elemN])
76the fifth call
arr.splice(start[, deleteCount, elem1, ..., elemN])
76
arr.splice(start[, deleteCount, elem1, ..., elemN])
78
arr.splice(start[, deleteCount, elem1, ..., elemN])
79

Here we can clearly see how the result of the previous call becomes the first argument of the next one.

We also can omit the initial value:

let arr = ["I", "study", "JavaScript", "right", "now"];

// remove 2 first elements
let removed = arr.splice(0, 2);

alert( removed ); // "I", "study" <-- array of removed elements
0

The result is the same. That’s because if there’s no initial, then

arr.splice(start[, deleteCount, elem1, ..., elemN])
51 takes the first element of the array as the initial value and starts the iteration from the 2nd element.

The calculation table is the same as above, minus the first row.

But such use requires an extreme care. If the array is empty, then

arr.splice(start[, deleteCount, elem1, ..., elemN])
51 call without initial value gives an error.

Here’s an example:

let arr = ["I", "study", "JavaScript", "right", "now"];

// remove 2 first elements
let removed = arr.splice(0, 2);

alert( removed ); // "I", "study" <-- array of removed elements
1

So it’s advised to always specify the initial value.

The method arr.reduceRight does the same, but goes from right to left.

Array.isArray

Arrays do not form a separate language type. They are based on objects.

So

arr.splice(start[, deleteCount, elem1, ..., elemN])
82 does not help to distinguish a plain object from an array:

let arr = ["I", "study", "JavaScript", "right", "now"];

// remove 2 first elements
let removed = arr.splice(0, 2);

alert( removed ); // "I", "study" <-- array of removed elements
2

…But arrays are used so often that there’s a special method for that: Array.isArray(value). It returns

let arr = ["t", "e", "s", "t"];

alert( arr.slice(1, 3) ); // e,s (copy from 1 to 3)

alert( arr.slice(-2) ); // s,t (copy from -2 till the end)
7 if the
arr.splice(start[, deleteCount, elem1, ..., elemN])
84 is an array, and
arr.concat(arg1, arg2...)
1 otherwise.

let arr = ["I", "study", "JavaScript", "right", "now"];

// remove 2 first elements
let removed = arr.splice(0, 2);

alert( removed ); // "I", "study" <-- array of removed elements
3

Most methods support “thisArg”

Almost all array methods that call functions – like

arr.splice(start[, deleteCount, elem1, ..., elemN])
11,
arr.splice(start[, deleteCount, elem1, ..., elemN])
20,
arr.splice(start[, deleteCount, elem1, ..., elemN])
44, with a notable exception of
arr.splice(start[, deleteCount, elem1, ..., elemN])
89, accept an optional additional parameter
arr.splice(start[, deleteCount, elem1, ..., elemN])
90.

That parameter is not explained in the sections above, because it’s rarely used. But for completeness we have to cover it.

Here’s the full syntax of these methods:

let arr = ["I", "study", "JavaScript", "right", "now"];

// remove 2 first elements
let removed = arr.splice(0, 2);

alert( removed ); // "I", "study" <-- array of removed elements
4

The value of

arr.splice(start[, deleteCount, elem1, ..., elemN])
90 parameter becomes
arr.splice(start[, deleteCount, elem1, ..., elemN])
92 for
arr.splice(start[, deleteCount, elem1, ..., elemN])
93.

For example, here we use a method of

arr.splice(start[, deleteCount, elem1, ..., elemN])
94 object as a filter, and
arr.splice(start[, deleteCount, elem1, ..., elemN])
90 passes the context:

let arr = ["I", "study", "JavaScript", "right", "now"];

// remove 2 first elements
let removed = arr.splice(0, 2);

alert( removed ); // "I", "study" <-- array of removed elements
5

If in the example above we used

arr.splice(start[, deleteCount, elem1, ..., elemN])
96, then
arr.splice(start[, deleteCount, elem1, ..., elemN])
97 would be called as a standalone function, with
arr.splice(start[, deleteCount, elem1, ..., elemN])
98, thus leading to an instant error.

A call to

arr.splice(start[, deleteCount, elem1, ..., elemN])
99 can be replaced with
let arr = ["I", "study", "JavaScript"];

arr.splice(1, 1); // from index 1 remove 1 element

alert( arr ); // ["I", "JavaScript"]
00, that does the same. The latter is used more often, as it’s a bit easier to understand for most people.

Summary

A cheat sheet of array methods:

  • To add/remove elements:

    • let arr = ["I", "study", "JavaScript"];
      
      arr.splice(1, 1); // from index 1 remove 1 element
      
      alert( arr ); // ["I", "JavaScript"]
      01 – adds items to the end,
    • let arr = ["I", "study", "JavaScript"];
      
      arr.splice(1, 1); // from index 1 remove 1 element
      
      alert( arr ); // ["I", "JavaScript"]
      02 – extracts an item from the end,
    • let arr = ["I", "study", "JavaScript"];
      
      arr.splice(1, 1); // from index 1 remove 1 element
      
      alert( arr ); // ["I", "JavaScript"]
      03 – extracts an item from the beginning,
    • let arr = ["I", "study", "JavaScript"];
      
      arr.splice(1, 1); // from index 1 remove 1 element
      
      alert( arr ); // ["I", "JavaScript"]
      04 – adds items to the beginning.
    • let arr = ["I", "study", "JavaScript"];
      
      arr.splice(1, 1); // from index 1 remove 1 element
      
      alert( arr ); // ["I", "JavaScript"]
      05 – at index
      let arr = ["I", "study", "JavaScript"];
      
      arr.splice(1, 1); // from index 1 remove 1 element
      
      alert( arr ); // ["I", "JavaScript"]
      06 deletes
      let arr = ["I", "study", "JavaScript"];
      
      // from index 2
      // delete 0
      // then insert "complex" and "language"
      arr.splice(2, 0, "complex", "language");
      
      alert( arr ); // "I", "study", "complex", "language", "JavaScript"
      7 elements and inserts
      let arr = ["I", "study", "JavaScript"];
      
      arr.splice(1, 1); // from index 1 remove 1 element
      
      alert( arr ); // ["I", "JavaScript"]
      08.
    • let arr = ["I", "study", "JavaScript"];
      
      arr.splice(1, 1); // from index 1 remove 1 element
      
      alert( arr ); // ["I", "JavaScript"]
      09 – creates a new array, copies elements from index
      let arr = ["I", "study", "JavaScript"];
      
      // from index 2
      // delete 0
      // then insert "complex" and "language"
      arr.splice(2, 0, "complex", "language");
      
      alert( arr ); // "I", "study", "complex", "language", "JavaScript"
      6 till
      let arr = [1, 2, 5];
      
      // from index -1 (one step from the end)
      // delete 0 elements,
      // then insert 3 and 4
      arr.splice(-1, 0, 3, 4);
      
      alert( arr ); // 1,2,3,4,5
      7 (not inclusive) into it.
    • let arr = ["I", "study", "JavaScript"];
      
      arr.splice(1, 1); // from index 1 remove 1 element
      
      alert( arr ); // ["I", "JavaScript"]
      12 – returns a new array: copies all members of the current one and adds
      let arr = ["I", "study", "JavaScript"];
      
      arr.splice(1, 1); // from index 1 remove 1 element
      
      alert( arr ); // ["I", "JavaScript"]
      08 to it. If any of
      let arr = ["I", "study", "JavaScript"];
      
      arr.splice(1, 1); // from index 1 remove 1 element
      
      alert( arr ); // ["I", "JavaScript"]
      08 is an array, then its elements are taken.
  • To search among elements:

    • let arr = ["I", "study", "JavaScript"];
      
      arr.splice(1, 1); // from index 1 remove 1 element
      
      alert( arr ); // ["I", "JavaScript"]
      15 – look for
      let arr = ["t", "e", "s", "t"];
      
      alert( arr.slice(1, 3) ); // e,s (copy from 1 to 3)
      
      alert( arr.slice(-2) ); // s,t (copy from -2 till the end)
      1 starting from position
      let arr = ["I", "study", "JavaScript"];
      
      arr.splice(1, 1); // from index 1 remove 1 element
      
      alert( arr ); // ["I", "JavaScript"]
      06, return the index or
      let arr = ["t", "e", "s", "t"];
      
      alert( arr.slice(1, 3) ); // e,s (copy from 1 to 3)
      
      alert( arr.slice(-2) ); // s,t (copy from -2 till the end)
      3 if not found.
    • let arr = ["I", "study", "JavaScript"];
      
      arr.splice(1, 1); // from index 1 remove 1 element
      
      alert( arr ); // ["I", "JavaScript"]
      19 – returns
      let arr = ["t", "e", "s", "t"];
      
      alert( arr.slice(1, 3) ); // e,s (copy from 1 to 3)
      
      alert( arr.slice(-2) ); // s,t (copy from -2 till the end)
      7 if the array has
      arr.splice(start[, deleteCount, elem1, ..., elemN])
      84, otherwise
      arr.concat(arg1, arg2...)
      1.
    • let arr = ["I", "study", "JavaScript"];
      
      arr.splice(1, 1); // from index 1 remove 1 element
      
      alert( arr ); // ["I", "JavaScript"]
      23 – filter elements through the function, return first/all values that make it return
      let arr = ["t", "e", "s", "t"];
      
      alert( arr.slice(1, 3) ); // e,s (copy from 1 to 3)
      
      alert( arr.slice(-2) ); // s,t (copy from -2 till the end)
      7.
    • arr.splice(start[, deleteCount, elem1, ..., elemN])
      15 is like
      arr.splice(start[, deleteCount, elem1, ..., elemN])
      11, but returns the index instead of a value.
  • To iterate over elements:

    • let arr = ["I", "study", "JavaScript"];
      
      arr.splice(1, 1); // from index 1 remove 1 element
      
      alert( arr ); // ["I", "JavaScript"]
      27 – calls
      arr.splice(start[, deleteCount, elem1, ..., elemN])
      93 for every element, does not return anything.
  • To transform the array:

    • let arr = ["I", "study", "JavaScript"];
      
      arr.splice(1, 1); // from index 1 remove 1 element
      
      alert( arr ); // ["I", "JavaScript"]
      29 – creates a new array from results of calling
      arr.splice(start[, deleteCount, elem1, ..., elemN])
      93 for every element.
    • let arr = ["I", "study", "JavaScript"];
      
      arr.splice(1, 1); // from index 1 remove 1 element
      
      alert( arr ); // ["I", "JavaScript"]
      31 – sorts the array in-place, then returns it.
    • let arr = ["I", "study", "JavaScript"];
      
      arr.splice(1, 1); // from index 1 remove 1 element
      
      alert( arr ); // ["I", "JavaScript"]
      32 – reverses the array in-place, then returns it.
    • let arr = ["I", "study", "JavaScript"];
      
      arr.splice(1, 1); // from index 1 remove 1 element
      
      alert( arr ); // ["I", "JavaScript"]
      33 – convert a string to array and back.
    • let arr = ["I", "study", "JavaScript"];
      
      arr.splice(1, 1); // from index 1 remove 1 element
      
      alert( arr ); // ["I", "JavaScript"]
      34 – calculate a single value over the array by calling
      arr.splice(start[, deleteCount, elem1, ..., elemN])
      93 for each element and passing an intermediate result between the calls.
  • Additionally:

    • let arr = ["I", "study", "JavaScript"];
      
      arr.splice(1, 1); // from index 1 remove 1 element
      
      alert( arr ); // ["I", "JavaScript"]
      36 checks
      arr.splice(start[, deleteCount, elem1, ..., elemN])
      84 for being an array, if so returns
      let arr = ["t", "e", "s", "t"];
      
      alert( arr.slice(1, 3) ); // e,s (copy from 1 to 3)
      
      alert( arr.slice(-2) ); // s,t (copy from -2 till the end)
      7, otherwise
      arr.concat(arg1, arg2...)
      1.

Please note that methods

arr.splice(start[, deleteCount, elem1, ..., elemN])
89,
let arr = ["I", "study", "JavaScript"];

arr.splice(1, 1); // from index 1 remove 1 element

alert( arr ); // ["I", "JavaScript"]
41 and
let arr = [1, 2, 5];

// from index -1 (one step from the end)
// delete 0 elements,
// then insert 3 and 4
arr.splice(-1, 0, 3, 4);

alert( arr ); // 1,2,3,4,5
1 modify the array itself.

These methods are the most used ones, they cover 99% of use cases. But there are few others:

  • arr.some(fn)/arr.every(fn) check the array.

    The function

    arr.splice(start[, deleteCount, elem1, ..., elemN])
    27 is called on each element of the array similar to
    arr.splice(start[, deleteCount, elem1, ..., elemN])
    44. If any/all results are
    let arr = ["t", "e", "s", "t"];
    
    alert( arr.slice(1, 3) ); // e,s (copy from 1 to 3)
    
    alert( arr.slice(-2) ); // s,t (copy from -2 till the end)
    7, returns
    let arr = ["t", "e", "s", "t"];
    
    alert( arr.slice(1, 3) ); // e,s (copy from 1 to 3)
    
    alert( arr.slice(-2) ); // s,t (copy from -2 till the end)
    7, otherwise
    arr.concat(arg1, arg2...)
    1.

    These methods behave sort of like

    let arr = ["I", "study", "JavaScript"];
    
    arr.splice(1, 1); // from index 1 remove 1 element
    
    alert( arr ); // ["I", "JavaScript"]
    48 and
    let arr = ["I", "study", "JavaScript"];
    
    arr.splice(1, 1); // from index 1 remove 1 element
    
    alert( arr ); // ["I", "JavaScript"]
    49 operators: if
    arr.splice(start[, deleteCount, elem1, ..., elemN])
    27 returns a truthy value,
    let arr = ["I", "study", "JavaScript"];
    
    arr.splice(1, 1); // from index 1 remove 1 element
    
    alert( arr ); // ["I", "JavaScript"]
    51 immediately returns
    let arr = ["t", "e", "s", "t"];
    
    alert( arr.slice(1, 3) ); // e,s (copy from 1 to 3)
    
    alert( arr.slice(-2) ); // s,t (copy from -2 till the end)
    7 and stops iterating over the rest of items; if
    arr.splice(start[, deleteCount, elem1, ..., elemN])
    27 returns a falsy value,
    let arr = ["I", "study", "JavaScript"];
    
    arr.splice(1, 1); // from index 1 remove 1 element
    
    alert( arr ); // ["I", "JavaScript"]
    54 immediately returns
    arr.concat(arg1, arg2...)
    1 and stops iterating over the rest of items as well.

    We can use

    let arr = ["I", "study", "JavaScript"];
    
    arr.splice(1, 1); // from index 1 remove 1 element
    
    alert( arr ); // ["I", "JavaScript"]
    56 to compare arrays:

    let arr = ["I", "study", "JavaScript", "right", "now"];
    
    // remove 2 first elements
    let removed = arr.splice(0, 2);
    
    alert( removed ); // "I", "study" <-- array of removed elements
    6

  • arr.fill(value, start, end) – fills the array with repeating

    arr.splice(start[, deleteCount, elem1, ..., elemN])
    84 from index
    let arr = ["I", "study", "JavaScript"];
    
    // from index 2
    // delete 0
    // then insert "complex" and "language"
    arr.splice(2, 0, "complex", "language");
    
    alert( arr ); // "I", "study", "complex", "language", "JavaScript"
    6 to
    let arr = [1, 2, 5];
    
    // from index -1 (one step from the end)
    // delete 0 elements,
    // then insert 3 and 4
    arr.splice(-1, 0, 3, 4);
    
    alert( arr ); // 1,2,3,4,5
    7.

  • arr.copyWithin(target, start, end) – copies its elements from position

    let arr = ["I", "study", "JavaScript"];
    
    // from index 2
    // delete 0
    // then insert "complex" and "language"
    arr.splice(2, 0, "complex", "language");
    
    alert( arr ); // "I", "study", "complex", "language", "JavaScript"
    6 till position
    let arr = [1, 2, 5];
    
    // from index -1 (one step from the end)
    // delete 0 elements,
    // then insert 3 and 4
    arr.splice(-1, 0, 3, 4);
    
    alert( arr ); // 1,2,3,4,5
    7 into itself, at position
    let arr = ["I", "study", "JavaScript"];
    
    arr.splice(1, 1); // from index 1 remove 1 element
    
    alert( arr ); // ["I", "JavaScript"]
    62 (overwrites existing).

  • arr.flat(depth)/arr.flatMap(fn) create a new flat array from a multidimensional array.

For the full list, see the manual.

From the first sight it may seem that there are so many methods, quite difficult to remember. But actually that’s much easier.

Look through the cheat sheet just to be aware of them. Then solve the tasks of this chapter to practice, so that you have experience with array methods.

Afterwards whenever you need to do something with an array, and you don’t know how – come here, look at the cheat sheet and find the right method. Examples will help you to write it correctly. Soon you’ll automatically remember the methods, without specific efforts from your side.