How to Fix the Problems with JavaScript Array Methods -Splice,Sort,Reverse
Tags: javascript, webdev, programming, react
Published: 2023-11-18 10:07:27

Most JavaScript beginners move fast breaking things while learning data structuresin JavaScript,stumbling on the bad parts of the language. Javascript is a dynamic and versatile programming language. easy to learn but understanding its deeper intricacies requires time and practice. 

In JavaScript, arrays are an object type that  contain unordered elements and can be modified once they are declared. There are numerous array methods (built-in functions) available in arrays for performing operationsincluding: sort, slice, reduce, filter, map, splice,some,find etc. There is even an entire lodash library with other helpful array methods.

Basically, an array method should not change or mutate the original array declaration instead it should always return a duplicate of the original.

 For example, the following `filter` should only return numbers more than five without  modifying the original array.


```javascript
let nums=[1,2,3,4,5,6,7,8,9,10]
let moreThanFive=nums.filter(num=>num>5)
// [6, 7, 8, 9, 10]
console.log(nums)
// [1,2,3,4,5,6,7,8,9,10]
```

As you can see, we have created a copy of  array `moreThanFive` with numbers more than 5 without modifying the original nums array. 

However there are useful array methods that does the job but also cause side effects by modifying the original array. That alone causes unnecessary side effects in our app; application performs poorly.

Lets  look at reverse method which should basically get a copy of nums in reverse wuthout modifying it.

```javascript
let nums=[1,2,3,4,5,6,7,8,9,10]
Let reverseNum=nums.reverse()
// [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
console.log(nums)
// [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
```

What happened?  Original array `nums` is also reversed! Why? It turns out some Javascript array methods modify an original array instead of simply grabbing a copy and that is detrimental in programming. Splice, Sort, and Reverse are three effective Javascript array methods that modify an original array. Let us examine them and explore ways to use them without modifying the original array. 

#### I want you to pay attention to changes in the original variable nums; our objective is keeping the original array unmodified.


## Splice

Splice ,as the name suggests, splits a section of array and optionally inserts an array element. It takes 3 arguments; the first one is required the rest are optional, 

**1.The index where splice should start**


```javascript
  let nums=[1,2,3,4,5,6,7,8,9,10]
let spliced = nums.splice(4) // get elements from index 4 to end
console.log(nums)  // [1, 2, 3, 4]
//5 to 10 have been removed
```
**2.The number of array elements to be removed (optional)**

```javascript
 let nums=[1,2,3,4,5,6,7,8,9,10]
let let spliced = nums.splice(4,2) // get  2 elements from index 4 onwards
console.log(nums) // [1, 2, 3, 4, 7, 8, 9, 10]
// 5,6 have been removed

```

**3.Array elements to add  from where you splice (optional)**

```javascript
let spliced = nums.splice(4,2,10,15) // get 2 elements from index 4 then add 10,15
console.log(nums)  // [1, 2, 3, 4, 10, 15, 7, 8, 9, 10]
// 5 and 6 have been removed but  10 and 15 have been added.
```

As you can see this method is really useful in creating new arrays but destroys the original array.

### The fix

**1.The old way; using array slice() method**
The slice Method is friendly method that preserve the original array and creates a copy. Combining it with Splice does the same as above but original array remain unmodified. 
Calling the slice method without arguments creates and return a copy of original array then splice that copy like so


```javascript
 let nums=[1,2,3,4,5,6,7,8,9,10]
let spliced = nums.slice().splice(4) // get elements from index 4 to end
console.log(nums)  // [1,2,3,4,5,6,7,8,9,10] //nums is untouched

let nums=[1,2,3,4,5,6,7,8,9,10]
let let spliced = nums.slice().splice(4,2) // get  2 elements from index 4 onwards
console.log(nums) // [1, 2, 3, 4, 7, 8, 9, 10] //nums is untouched
```
**2.ES2023 toSpliced() method**

EcmaScript 2023 aka ES2023  introduced the array toSpliced() method which simply splices an original array and return a copy without modifying it.

```javascript
let nums=[1,2,3,4,5,6,7,8,9,10]
let spliced = nums.slice().toSpliced(4) // get elements from index 4 to end
console.log(nums)  // [1,2,3,4,5,6,7,8,9,10] //nums is untouched
```


## Sort
The sort method arranges elements in ascending or descending order depending on the data type.
Let's shuffle and sort our numbers array. I'll just use my hands to shuffle because Javascript, unlike PHP, doesn't provide a shuffle array function.

```javascript
let nums=[1,7,3,10,5,6,2,8,9,4]
let sorted=nums.sort()
console.log(nums) //  [1, 10, 2, 3, 4, 5, 6, 7, 8, 9]
```
 Our original array nums is modified even though the sort() method failed miserably.
It turns out Javascript has a problem sorting arrays, so we have to pass in a callback function telling it how to sort our array.

```javascript
let nums=[1,7,3,10,5,6,2,8,9,4]
let sorted=nums.sort(((a,z)=>a-z) //ascending order
console.log(nums) //  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] // It modified nums but sorted correctly
```

### The fix

**1.The old way; using array slice**
We slice  the whole original array using the slice method once more, then we sort it explicitly.

```javascript
let nums=[1,7,3,10,5,6,2,8,9,4]
let sorted=nums.slice().sort() // [1, 7, 3, 10, 5, 6, 2, 8, 9, 4]
```

Mission accomplished, nums is untouched but sorted array is incorrectly sorted, can you figure out how to do that?


**2.ES2023 toSorted() method**
ES2023 added another Javascript array method,a friendly sister to sort, toSorted() sorts an array without modifying the original.

```javascript
let nums=[1,7,3,10,5,6,2,8,9,4]
let sorted=nums.toSorted((a,z)=>a-z) // ascending order
console.log(nums) // [1, 7, 3, 10, 5, 6, 2, 8, 9, 4] // untouched
console.log(sorted) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]  //sorted correctly
```

## Reverse
Array reverse method does what it does, it reverses an array forward-back or back-forward but it leaves the original array in wrecked state.

```javascript
let nums=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
let reversed=nums.reverse()
console.log(nums) // [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
```

As you can see nums is also reversed, let fix that.

### the fix

**1.The slice method**
The slice method is a must have tool in javascript, be it strings or arrays, it copies and leaves no damage behind.

```javascript
let nums=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
let reversed=nums.slice().reverse()
console.log(nums) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
```

**2.ES2023 toReversed() method**
EcmaScript 2023 introduced a polite toReversed method, a friendly sister of reverse

```javascript
et nums=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
let reversed=nums.toReversed()
console.log(nums) //  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
console.log(reversed) // [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
```

## Don’t break the internet!!


Be careful not to break the internet as ES2023 features are supported by latest browser versions; Google Chrome 110 and above support it, latest versions of Mozilla,Safariand edge offer support.

Here is the error that occurs when you try `toReversed()` on Mozilla Firefox version 78.

The work around for this scenario is to run  feature detection on the browser before using the feature else fallback to the old ways.You that by checking if `Array prototype` has the new method.

```javascript
if(Array.prototype.toReversed){
console.log(" toReversed() is supported, use ES2023")

let nums=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
let reversed=nums.slice().reverse()
}else{
console.log(" toReversed() is not supported, use the old tricks")
let nums=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
let reversed=nums.slice().reverse()
}

```

## A word on React Library


React, a JavaScript UI library, understands the impact of this methods on data transformation and thus uses ` map,filter and reduce` methods  incessantly as workhorses as they do not have side effect to app performance.

In conclusion, some array methods perform the expected functions but also give unusual side effect which can hurt the performance of an application.