Understanding the slice method in javascript: the basics, negative indexing and the concept of shallow copy
Tags: javascript, webdev, jsarrays
Published: 2020-06-07 19:30:12


This article is for you:

1.  If you are an absolute beginner in JS.
2.  If you have copied and pasted a chunk of code from stackoverflow which had `slice()` method but didn't understand the code completely.
3.  If you have used it earlier and have been planning to get a deeper understanding of it.
4.  And its definitely for you if you thought there couldn't be an 2500+ words article merely on slice() method.

The name suggests it clearly. All that `slice()` method does is get us a _slice(a portion)_ of _**things**_. In this article we will discuss what are those _**things**_, how do we _slice_ them and a few other aspects of the `slice()` method. First question:

**What are the *things* we can get a *slice* of?**

There are two types of  _**things**_(more appropriately called `objects`) which we can get a _slice_ of.  In technical terms, the `slice()` method can be applied to two types of objects in Javascript: _Strings and Arrays_.

#### _**String samples**_
```javascript

    //Examples of String Objects in Javascript

    let str_greet = new String("Hey! Developers");
    let str_numbers = new String("987654321");
    let str_spcl_chars = new String("@@###!!");
    let str_zeros = new String("000000");

    //The following are 'strings' but not 'String objects'
    //However the 'slice()' method can be applied to them too
    let greet = "Hello World";
    let num_str = "12345";
```

#### _**Array samples**_
```javascript

    //Examples of Arrays in Javascript

    let fruits = ["apple", "mango", "banana", "grapes", "blueberry", "kiwi", "papaya"];
    let even_arr = [2, 4, 6, 8, 10];
    let str_numb_arr = ["4", "10", "40", "5"]; 
    let mixed_arr = ["John", "Doe", 32, "1988"]; 
```

To get into details of what _Strings and Arrays are in Javascript_ is beyond the scope of this article. The method's behavior is almost same in both the cases. It will either return a _sub-string or a sub-array._ Just note that most of the discussion and examples are going to be about `Array.Slice()` method.  Let's get started.

## **The Basics**

<picture><source srcset="https://foxbits.dev/sites/default/files/inline-images/array-slice-example-fruits-for-fact-0.jpg 1x" media="all and (min-width: 851px)" type="image/jpeg"><source srcset="https://foxbits.dev/sites/default/files/inline-images/array-slice-example-fruits-for-fact-0.jpg 1x" media="all and (min-width: 560px) and (max-width: 850px)" type="image/jpeg"><source srcset="https://foxbits.dev/sites/default/files/styles/content_image_mobile_scale_600_/public/inline-images/array-slice-example-fruits-for-fact-0.jpg?itok=2X9PRGni 1x" type="image/jpeg">![Javascript Array Slice Method: A Basic Example](https://foxbits.dev/sites/default/files/inline-images/array-slice-example-fruits-for-fact-0.jpg)</picture>

The Slice method returns a _portion_ of an array into a new array. Which portion it returns is decided by two _optional_ _parameters_ **begin** and **end**.

### **Syntax**

`arr.slice([begin[, end]])`

```javascript
    let fruits = ["apple", "mango", "banana", "grapes", "blueberry", "kiwi", "papaya"];
    let my_fav_fruits = fruits.slice(2,4);

    console.log(my_fav_fruits);
    // output -> [ 'banana', 'grapes' ] 

    console.log(fruits);
    // output -> [ 'apple', 'mango', 'banana', 'grapes', 'blueberry', 'kiwi', 'papaya' ] 
```

 Now that we have seen a basic example, let's discuss some of the **_facts_** related to the method.

**Slice Fact 1**: The original array is not modified. The newly formed array assigned to `my_fav_fruits` variable is just a copy of a portion of the original array `fruits`. The original array remains intact. The new array is often referred as a _shallow copy_ of the original array which we will discuss later in the article.

<picture><source srcset="https://foxbits.dev/sites/default/files/inline-images/array-slice-example-fruits-for-fact-xx.jpg 1x" media="all and (min-width: 851px)" type="image/jpeg"><source srcset="https://foxbits.dev/sites/default/files/inline-images/array-slice-example-fruits-for-fact-xx.jpg 1x" media="all and (min-width: 560px) and (max-width: 850px)" type="image/jpeg"><source srcset="https://foxbits.dev/sites/default/files/styles/content_image_mobile_scale_600_/public/inline-images/array-slice-example-fruits-for-fact-xx.jpg?itok=6IGFDHcn 1x" type="image/jpeg">![Javascript array slice method. The original array vs the new array.](https://foxbits.dev/sites/default/files/inline-images/array-slice-example-fruits-for-fact-xx.jpg)</picture>

<picture><source srcset="https://foxbits.dev/sites/default/files/inline-images/array-slice-example-fruits-for-fact-xx2.jpg 1x" media="all and (min-width: 851px)" type="image/jpeg"><source srcset="https://foxbits.dev/sites/default/files/inline-images/array-slice-example-fruits-for-fact-xx2.jpg 1x" media="all and (min-width: 560px) and (max-width: 850px)" type="image/jpeg"><source srcset="https://foxbits.dev/sites/default/files/styles/content_image_mobile_scale_600_/public/inline-images/array-slice-example-fruits-for-fact-xx2.jpg?itok=loxKRhqg 1x" type="image/jpeg">![The original array remains same after applying slice method](https://foxbits.dev/sites/default/files/inline-images/array-slice-example-fruits-for-fact-xx2.jpg)</picture>

**Slice Fact 2**: The item at the end position is not included in the new array. As we can see in the example below, the item at the 5th position (_Kiwi_) is not included in the output array(`my_fav_fruits`).

<picture><source srcset="https://foxbits.dev/sites/default/files/inline-images/javascript-array-slice-method-foxbits-fact-1_0.jpg 1x" media="all and (min-width: 851px)" type="image/jpeg"><source srcset="https://foxbits.dev/sites/default/files/inline-images/javascript-array-slice-method-foxbits-fact-1_0.jpg 1x" media="all and (min-width: 560px) and (max-width: 850px)" type="image/jpeg"><source srcset="https://foxbits.dev/sites/default/files/styles/content_image_mobile_scale_600_/public/inline-images/javascript-array-slice-method-foxbits-fact-1_0.jpg?itok=iKiAubbT 1x" type="image/jpeg">![Javascript Array Slice Method The End Element is not included](https://foxbits.dev/sites/default/files/inline-images/javascript-array-slice-method-foxbits-fact-1_0.jpg)</picture>

```javascript
    let fruits = ["apple", "mango", "banana", "grapes", "blueberry", "kiwi", "papaya"];
    let my_fav_fruits = fruits.slice(1,5);

    console.log(my_fav_fruits);
    // output -> [ 'mango', 'banana', 'grapes', 'blueberry' ] 
```

**Slice Fact 3**: If _end_ is not provided, then it assumes the end parameter to be '_the actual end of the array_', which is equivalent to the `length` of the array(`fruits.length`).

<picture><source srcset="https://foxbits.dev/sites/default/files/inline-images/xxjavascript-array-slice-method-foxbits-fact-2.jpg 1x" media="all and (min-width: 851px)" type="image/jpeg"><source srcset="https://foxbits.dev/sites/default/files/inline-images/xxjavascript-array-slice-method-foxbits-fact-2.jpg 1x" media="all and (min-width: 560px) and (max-width: 850px)" type="image/jpeg"><source srcset="https://foxbits.dev/sites/default/files/styles/content_image_mobile_scale_600_/public/inline-images/xxjavascript-array-slice-method-foxbits-fact-2.jpg?itok=lGhXWyes 1x" type="image/jpeg">![Javascript Array Slice Method: The default end parameter is length of the array](https://foxbits.dev/sites/default/files/inline-images/xxjavascript-array-slice-method-foxbits-fact-2.jpg)</picture>

```javascript
    let fruits = ["apple", "mango", "banana", "grapes", "blueberry", "kiwi", "papaya"];
    let my_fav_fruits = fruits.slice(2);

    console.log(my_fav_fruits);
    // output -> [ 'banana', 'grapes', 'blueberry', 'kiwi', 'papaya' ]
```

**Slice Fact 4**: If the second parameter (_end_) is a number higher than the `length` of the array, then the resulting array is exactly the same as in **Slice Fact 3**. It returns the elements through '_the actual end of the array_', which is equivalent to the `length` of the array(`fruits.length`).

<picture><source srcset="https://foxbits.dev/sites/default/files/inline-images/array-slice-example-fruits-for-fact-3_0.jpg 1x" media="all and (min-width: 851px)" type="image/jpeg"><source srcset="https://foxbits.dev/sites/default/files/inline-images/array-slice-example-fruits-for-fact-3_0.jpg 1x" media="all and (min-width: 560px) and (max-width: 850px)" type="image/jpeg"><source srcset="https://foxbits.dev/sites/default/files/styles/content_image_mobile_scale_600_/public/inline-images/array-slice-example-fruits-for-fact-3_0.jpg?itok=DWcDI38n 1x" type="image/jpeg">![Javascript Array Slice Method: When the end value is higher than actual length of array.](https://foxbits.dev/sites/default/files/inline-images/array-slice-example-fruits-for-fact-3_0.jpg)</picture>

```javascript
    let fruits = ["apple", "mango", "banana", "grapes", "blueberry", "kiwi", "papaya"];
    let my_fav_fruits = fruits.slice(2,100);

    console.log(my_fav_fruits);
    // output -> [ 'banana', 'grapes', 'blueberry', 'kiwi', 'papaya' ]
```

**Slice Fact 5**: Since both the parameters are optional, its _perfectly valid_ to call the method _with no parameters_ at all. In such case it returns the exact _copy of the original array_. This feature is sometimes used to get a copy of an array in Javascript.

<picture><source srcset="https://foxbits.dev/sites/default/files/inline-images/array-slice-example-fruits-for-fact-4_0.jpg 1x" media="all and (min-width: 851px)" type="image/jpeg"><source srcset="https://foxbits.dev/sites/default/files/inline-images/array-slice-example-fruits-for-fact-4_0.jpg 1x" media="all and (min-width: 560px) and (max-width: 850px)" type="image/jpeg"><source srcset="https://foxbits.dev/sites/default/files/styles/content_image_mobile_scale_600_/public/inline-images/array-slice-example-fruits-for-fact-4_0.jpg?itok=xi16t3ob 1x" type="image/jpeg">![​ Edit media Image  When both parameters are missing, it creates copy of the original array](https://foxbits.dev/sites/default/files/inline-images/array-slice-example-fruits-for-fact-4_0.jpg)</picture>

```javascript
    let fruits = ["apple", "mango", "banana", "grapes", "blueberry", "kiwi", "papaya"];
    let my_fav_fruits = fruits.slice();

    console.log(my_fav_fruits);
    // output ->[ 'apple', 'mango', 'banana', 'grapes', 'blueberry', 'kiwi', 'papaya' ]
```

**Slice Fact 6**: For the first parameter(_begin_), `undefined` value is accepted and considered as **0**. The returned array has elements from the _starting_ position.

<picture><source srcset="https://foxbits.dev/sites/default/files/inline-images/array-slice-example-fruits-for-fact-5.jpg 1x" media="all and (min-width: 851px)" type="image/jpeg"><source srcset="https://foxbits.dev/sites/default/files/inline-images/array-slice-example-fruits-for-fact-5.jpg 1x" media="all and (min-width: 560px) and (max-width: 850px)" type="image/jpeg"><source srcset="https://foxbits.dev/sites/default/files/styles/content_image_mobile_scale_600_/public/inline-images/array-slice-example-fruits-for-fact-5.jpg?itok=TU4dsBTn 1x" type="image/jpeg">![Javascript Array Slice Method: If first parameter is undefined, then the result contains elements from the starting point of the array.](https://foxbits.dev/sites/default/files/inline-images/array-slice-example-fruits-for-fact-5.jpg)</picture>

```javascript
    let fav_fruits = ["apple", "mango", "banana", "grapes", "blueberry", "kiwi", "papaya"];
    let my_fav_fruits = fav_fruits.slice(undefined, 5);

    console.log(my_fav_fruits);
    //output -> [ 'apple', 'mango', 'banana', 'grapes', 'blueberry' ]
```

**Slice Fact 7**: If the first parameter(_begin_) is greater than or equal to the _length of the array_, then an `empty array` will be returned.

<picture><source srcset="https://foxbits.dev/sites/default/files/inline-images/array-slice-example-fruits-for-fact-6_0.jpg 1x" media="all and (min-width: 851px)" type="image/jpeg"><source srcset="https://foxbits.dev/sites/default/files/inline-images/array-slice-example-fruits-for-fact-6_0.jpg 1x" media="all and (min-width: 560px) and (max-width: 850px)" type="image/jpeg"><source srcset="https://foxbits.dev/sites/default/files/styles/content_image_mobile_scale_600_/public/inline-images/array-slice-example-fruits-for-fact-6_0.jpg?itok=dr5C3ZBR 1x" type="image/jpeg">![Javascript Array Slice Method: When begin is greater than or equal to length of array.](https://foxbits.dev/sites/default/files/inline-images/array-slice-example-fruits-for-fact-6_0.jpg)</picture>

```javascript
    let fav_fruits = ["apple", "mango", "banana", "grapes", "blueberry", "kiwi", "papaya"];
    let my_fav_fruits = fav_fruits.slice(100, 5);

    console.log(my_fav_fruits);
    //output -> []
```
&nbsp;

## **Negative Indexing**

The slice method supports the negative indexing. To understand this, let's look at the image below. The items at the last position are indexed as `-1` and the one at second to last position as `-2` and so on. While the positive indexing moves from _left to right_, the negative one moves from _right to left_. With this kind of indexing, the _index_ of first element is '_negative value of the length of the array_'.

<picture><source srcset="https://foxbits.dev/sites/default/files/inline-images/array-slice-example-fruits-for-fact-negative-index.jpg 1x" media="all and (min-width: 851px)" type="image/jpeg"><source srcset="https://foxbits.dev/sites/default/files/inline-images/array-slice-example-fruits-for-fact-negative-index.jpg 1x" media="all and (min-width: 560px) and (max-width: 850px)" type="image/jpeg"><source srcset="https://foxbits.dev/sites/default/files/styles/content_image_mobile_scale_600_/public/inline-images/array-slice-example-fruits-for-fact-negative-index.jpg?itok=fdQPYrRN 1x" type="image/jpeg">![Negative Indexing of array elements in Javascript](https://foxbits.dev/sites/default/files/inline-images/array-slice-example-fruits-for-fact-negative-index.jpg)</picture>

Let's see a few examples of how `slice()` works with the negative indexing. To continue the Slice Facts list, let's add the eighth one:

**Slice Fact 8**: The method works perfectly fine with negative indexes. The working mechanism is same as we saw earlier. Only the indexing changes.

<picture><source srcset="https://foxbits.dev/sites/default/files/inline-images/array-slice-example-fruits-for-fact-8.jpg 1x" media="all and (min-width: 851px)" type="image/jpeg"><source srcset="https://foxbits.dev/sites/default/files/inline-images/array-slice-example-fruits-for-fact-8.jpg 1x" media="all and (min-width: 560px) and (max-width: 850px)" type="image/jpeg"><source srcset="https://foxbits.dev/sites/default/files/styles/content_image_mobile_scale_600_/public/inline-images/array-slice-example-fruits-for-fact-8.jpg?itok=qfeHgCnu 1x" type="image/jpeg">![Slice method with negative index works fine](https://foxbits.dev/sites/default/files/inline-images/array-slice-example-fruits-for-fact-8.jpg)</picture>

```javascript
    let fav_fruits = ["apple", "mango", "banana", "grapes", "blueberry", "kiwi", "papaya"];
    let my_fav_fruits = fav_fruits.slice(-5, -1);

    console.log(my_fav_fruits);
    //output -> [ 'banana', 'grapes', 'blueberry', 'kiwi' ]
```

**Slice Fact 9**: Utilizing the negative indexing property, you can get the last '_x number of elements_' from an array calling `slice(-x)`.

In the example below, we are fetching the 'last 4 elements' of the fruits array. We put the _begin(first parameter)_ as `-4` and omit the _end(second parameter)_. The logic behind this is very simple. The items from the position `-4` to the `end(-4, -3, -2 and -1)` are being returned.

<picture><source srcset="https://foxbits.dev/sites/default/files/inline-images/array-slice-example-fruits-for-fact-9.jpg 1x" media="all and (min-width: 851px)" type="image/jpeg"><source srcset="https://foxbits.dev/sites/default/files/inline-images/array-slice-example-fruits-for-fact-9.jpg 1x" media="all and (min-width: 560px) and (max-width: 850px)" type="image/jpeg"><source srcset="https://foxbits.dev/sites/default/files/styles/content_image_mobile_scale_600_/public/inline-images/array-slice-example-fruits-for-fact-9.jpg?itok=1YelBoBz 1x" type="image/jpeg">![Using Slice with negative index to fetch last 4 elements of an array](https://foxbits.dev/sites/default/files/inline-images/array-slice-example-fruits-for-fact-9.jpg)</picture>

```javascript
    let fav_fruits = ["apple", "mango", "banana", "grapes", "blueberry", "kiwi", "papaya"];
    let my_fav_fruits = fav_fruits.slice(-4);

    console.log(my_fav_fruits);
    //output -> [ 'grapes', 'blueberry', 'kiwi', 'papaya' ]
```

**Slice Fact 10**: The mix of _negative_ and _positive_ index works perfectly fine. However one needs to be careful while doing so as it can be a bit confusing. The thumb rule in most cases is: You will just have to make sure the position of the first parameter is on the left side of the second parameter. Otherwise, you will get an empty array. While this may look a bit confusing initially, if you look at the _indexes_ closely, it becomes very simple.

<picture><source srcset="https://foxbits.dev/sites/default/files/inline-images/array-slice-example-fruits-for-fact-10.jpg 1x" media="all and (min-width: 851px)" type="image/jpeg"><source srcset="https://foxbits.dev/sites/default/files/inline-images/array-slice-example-fruits-for-fact-10.jpg 1x" media="all and (min-width: 560px) and (max-width: 850px)" type="image/jpeg"><source srcset="https://foxbits.dev/sites/default/files/styles/content_image_mobile_scale_600_/public/inline-images/array-slice-example-fruits-for-fact-10.jpg?itok=X6i-XZB4 1x" type="image/jpeg">![Using slice method with mix of positive and negative index.](https://foxbits.dev/sites/default/files/inline-images/array-slice-example-fruits-for-fact-10.jpg)</picture>

```javascript
    let fav_fruits = ["apple", "mango", "banana", "grapes", "blueberry", "kiwi", "papaya"];
    let my_fav_fruits = fav_fruits.slice(-6, 5);

    console.log(my_fav_fruits);
    //output -> [ 'mango', 'banana', 'grapes', 'blueberry' ]
```
&nbsp; 

## **Shallow Copy**

As mentioned earlier in the article, let's discuss what **shallow copy** means. This will help us determine when to use `slice()`, when to avoid it and when to be extra cautious while using it.  But before getting into it, I will write a quick summary of _primitive and non-primitive_ data types in javascript. This is important to understand the concept of 'shallow copy' that the `slice()` method adopts while creating a copy of an array.

So far, we have seen arrays in our examples where elements are _plain strings and numbers_. Instead of calling them _plain_, programming world has a special term for them called _primitive_. To be honest, the detailed discussion of primitive and non-primitive will take another 30 minutes or more. I will keep short and simple by putting only relevant items in the list here. 

#### **Primitive Values**

*   _numbers_
*   _strings_
*   _boolean_

#### **Non Primitive Values**

*   _Objects_
*   _Arrays (which is actually a special kind of object)_

The way primitive data is stored in computer's memory is different from the way non-primitives are stored. _Primitives_ are stored by **_values_** whereas _non-primitives_ are stored **_by references_**. Let's see what that means with examples.

```javascript
    //primitive values

    let a = 5;
    let grt_str = "Hello World";
    let bool_val = 0;
```

When I execute the above lines, JS will tell computer:

1.  Hey computer, I have this variable named '`a`' and remember its value is **5**. 
2.  Hey computer, I have this variable named '`grt_str`' and remember its value is "**Hello World**".
3.  Hey computer, I have this variable named '`bool_val`' and remember its value is **0**.

```javascript
    // Non Primitive Values

    let fox_arr = ["JS", "Python", "PHP"];

    let fox_obj = {
        'name': 'FoxBits',
        'type': 'web',
        'age' : 2
    };
```

Here, when I execute the above lines, JS will tell computer:

1.  Hey computer, I have this array  named '`fox_arr`'. Save it in your memory and tell me the **_address of the memory block where you stored it_**.
2.  Hey computer, I have this object named '`fox_obj`'. Save it in your memory and tell me the _**address of the memory block where you stored it**_.

I hope this gave some idea on how _primitives and no primitives_ are stored differently in javascript. All these will make sense soon, I promise. We will now create an array which will contain all of the above declared values: both primitive and non-primitive ones.

```javascript

    //this array has 3 primitive and 2 non primitive values

    let mixed_array = [a, grt_str, bool_val, fox_arr, fox_obj]
```

I want to show you a roughly designed graphical representation of how this array(`mixed_array`) will be stored in memory. Consider the yellow boxes as memory blocks.

<picture><source srcset="https://foxbits.dev/sites/default/files/inline-images/primitive-and-non-primitive-data-stored-in-memory-javascript.jpg 1x" media="all and (min-width: 851px)" type="image/jpeg"><source srcset="https://foxbits.dev/sites/default/files/inline-images/primitive-and-non-primitive-data-stored-in-memory-javascript.jpg 1x" media="all and (min-width: 560px) and (max-width: 850px)" type="image/jpeg"><source srcset="https://foxbits.dev/sites/default/files/styles/content_image_mobile_scale_600_/public/inline-images/primitive-and-non-primitive-data-stored-in-memory-javascript.jpg?itok=WWBUGRNy 1x" type="image/jpeg">![Primitive and non-primitive data stored in memory in javascript](https://foxbits.dev/sites/default/files/inline-images/primitive-and-non-primitive-data-stored-in-memory-javascript.jpg)</picture>

As you can see in the image above, for the primitive data_(a, grt_str and bool_val)_ the values are stored directly in the memory blocks. Whereas for the non-primitive ones(_fox_arr and fox_obj_), the data is stored in **two layers**. In the first layer, the memory reference to _fox_arr_ and _fox_obj_ are stored. In the second layer, the _actual array_ and object items are stored.

Now, lets get back to the concept of 'shallow copy'. When we say the `slice()` method creates a shallow copy, it implies that only the **_first layer_** is copied into the new array. This means that for the ones in the first layer, the primitive values, a _**new copy with values**_ is created for each item. But for the items in the second layer, only the **_memory references_** are copied. Suppose I execute the following script:

```javascript
    // Using slice without parameters 
    // will create a shallow copy of all the elements in original array

    let new_mixed_array = mixed_array.slice();
```

Then the storage of `new_mixed_array`, a copy of `mixed_array` in memory blocks will look something like this:

<picture><source srcset="https://foxbits.dev/sites/default/files/inline-images/shallow-copy-created-by-slice-method-in-javascript-example.jpg 1x" media="all and (min-width: 851px)" type="image/jpeg"><source srcset="https://foxbits.dev/sites/default/files/inline-images/shallow-copy-created-by-slice-method-in-javascript-example.jpg 1x" media="all and (min-width: 560px) and (max-width: 850px)" type="image/jpeg"><source srcset="https://foxbits.dev/sites/default/files/styles/content_image_mobile_scale_600_/public/inline-images/shallow-copy-created-by-slice-method-in-javascript-example.jpg?itok=ZYflSvVM 1x" type="image/jpeg">![shallow copy created by slice method in javascript](https://foxbits.dev/sites/default/files/inline-images/shallow-copy-created-by-slice-method-in-javascript-example.jpg)</picture>

What we can infer from the image above is:

1\. In the newly created _copy of `mixed_array`_, the primitive values are copied as values. This means that if we alter these values in the new array, the corresponding values in the original array will not change. And vice versa.

2\. In this copy, the non-primitive values are copied as reference. They are still referencing to the objects in the original `_mixed_array_`. This means that if we make any change in these items in the new array then the original values will also change. And vice versa.

Let's try out the same in code below. I will copy the relevant code from the above code blocks and make some changes to the `new_mixed_array` and then check the original array.

```javascript
    //primitive values
    let a = 5;
    let grt_str = "Hello World";
    let bool_val = 0;

    // Non Primitive Values
    let fox_arr = ["JS", "Python", "PHP"];
    let fox_obj = {
        'name': 'FoxBits',
        'type': 'web',
        'age' : 2
    };

    //this array has 3 primitive and 2 non primitive values
    let mixed_array = [a, grt_str, bool_val, fox_arr, fox_obj]

    console.log(mixed_array);
```

This is the output of `console.log()` before using any method.

<picture><source srcset="https://foxbits.dev/sites/default/files/inline-images/javascript-shallow-copy-output-1.png 1x" media="all and (min-width: 851px)" type="image/png"><source srcset="https://foxbits.dev/sites/default/files/inline-images/javascript-shallow-copy-output-1.png 1x" media="all and (min-width: 560px) and (max-width: 850px)" type="image/png"><source srcset="https://foxbits.dev/sites/default/files/styles/content_image_mobile_scale_600_/public/inline-images/javascript-shallow-copy-output-1.png?itok=n8-mFAJU 1x" type="image/png">![Javascript array before changing new array](https://foxbits.dev/sites/default/files/inline-images/javascript-shallow-copy-output-1.png)</picture>

```javascript
    // Using slice without parameters 
    // will create a shallow copy of all the elements in original array

    let new_mixed_array = mixed_array.slice();

    // Changing the first item in the new_mixed_array
    new_mixed_array[0] = '10'

    // Logging the original array to check if anything has changed
    console.log(mixed_array);
```

As expected, this will cause no change in the original array. The same output for the original array can be seen again. This is because we updated a primitive value.

<picture><source srcset="https://foxbits.dev/sites/default/files/inline-images/javascript-shallow-copy-output-2.png 1x" media="all and (min-width: 851px)" type="image/png"><source srcset="https://foxbits.dev/sites/default/files/inline-images/javascript-shallow-copy-output-2.png 1x" media="all and (min-width: 560px) and (max-width: 850px)" type="image/png"><source srcset="https://foxbits.dev/sites/default/files/styles/content_image_mobile_scale_600_/public/inline-images/javascript-shallow-copy-output-2.png?itok=WgtXx8MZ 1x" type="image/png">![Javascript array after changing new array](https://foxbits.dev/sites/default/files/inline-images/javascript-shallow-copy-output-2.png)</picture>    

Here comes the important step. Lets make some change to an array in the `new_mixed_array`. We will target the third item of the fourth element which is '**PHP**'. We will replace '**PHP**' with '**Flutter**' in the new array and then will log the original array in console.

```javascript
    // new_mixed_array[3] is an array with three elements
    // the third element is 'PHP'
    // we intend to replace it with 'Flutter'

    new_mixed_array[3][2] = 'Flutter';

    console.log(mixed_array);
```

<picture><source srcset="https://foxbits.dev/sites/default/files/inline-images/javascript-shallow-copy-allows-changes-in-referenced-objects.jpg 1x" media="all and (min-width: 851px)" type="image/jpeg"><source srcset="https://foxbits.dev/sites/default/files/inline-images/javascript-shallow-copy-allows-changes-in-referenced-objects.jpg 1x" media="all and (min-width: 560px) and (max-width: 850px)" type="image/jpeg"><source srcset="https://foxbits.dev/sites/default/files/styles/content_image_mobile_scale_600_/public/inline-images/javascript-shallow-copy-allows-changes-in-referenced-objects.jpg?itok=7l0NKY-t 1x" type="image/jpeg">![Javascript shallow copy allows changes in referenced objects](https://foxbits.dev/sites/default/files/inline-images/javascript-shallow-copy-allows-changes-in-referenced-objects.jpg)</picture>

Now that we have seen what shallow copy means, we have good reasons to be cautious while using the `slice()` method if the array contains non-primitive element(s). There are times when developers use it and expect the new array to be independent of the original array, which may not always be the case.

Let's discuss the last topic and then we will wrap up.

## **The slice() method for Strings**

So far we only saw arrays being sliced. But as mentioned in the beginning of the article, _slice()_ is also available for _**Strings**_. The behavior for Strings is almost same as for _**Arrays**_. The first difference is that the items involved in the process are part of a string, not elements of array. And similarly the output is a string, not an array. To understand it just a single example for String slice will suffice.

<picture><source srcset="https://foxbits.dev/sites/default/files/inline-images/string-slice.jpg 1x" media="all and (min-width: 851px)" type="image/jpeg"><source srcset="https://foxbits.dev/sites/default/files/inline-images/string-slice.jpg 1x" media="all and (min-width: 560px) and (max-width: 850px)" type="image/jpeg"><source srcset="https://foxbits.dev/sites/default/files/styles/content_image_mobile_scale_600_/public/inline-images/string-slice.jpg?itok=iC0n4euD 1x" type="image/jpeg">![Javascript String Slice Method](https://foxbits.dev/sites/default/files/inline-images/string-slice.jpg)</picture>

```javascript
    let str_greet = new String("Hey! Developers");
    let greet_sub = str_greet.slice(0, 4);

    console.log(greet_sub);
```

&nbsp; 
## **Summary**

Let's summarize the article.

`Slice()` method is available for _**Strings and Arrays**_ in Javascript.

It has two _optional_ parameters which we can use in different combinations to get interesting results.

It does not make modifications to the original array/string.

We can use _negative indexes_ with the `slice()` method which makes it even more useful.

The method returns a **_shallow copy_** of the original array into a new array.

Thus, in the new array primitive values get a _new copy_ whereas the non-primitives get only the _copy of reference_ to original objects.

For non-primitive values, any changes done in the resulting array items will be reflected to the original array and vice-versa.

I hope this article helped. If you liked it I recommend another one related to javascript's `push()`, `pop()`, `shift()` and `unshift()` methods. It has graphics too which will help you understand the concepts easily.

[The four common Javascript array methods Push, Pop, Shift and Unshift](https://webtechparadise.com/article/four-common-javascript-array-methods-push-pop-shift-and-unshift/15)

*This article was originally published in [WebTechParadise](https://webtechparadise.com/article/understanding-slice-method-javascript-basics-negative-indexing-and-concept-shallow-copy/17"Javascript Array Methods Push, Pop, Shift and Unshift by WebTechParadise")*