DEV Community

loading...
Cover image for 5 Way to Append Item to Array in JavaScript

5 Way to Append Item to Array in JavaScript

samanthaming profile image Samantha Ming Originally published at samanthaming.com ใƒปUpdated on ใƒป6 min read

Alt Text

Here are 5 ways to add an item to the end of an array. push, splice, and length will mutate the original array. Whereas concat and spread will not and will instead return a new array. Which is the best depends on your use case ๐Ÿ‘

Mutative

This will change the original array

const array = ['๐ŸฆŠ'];

array.push('๐Ÿด');
array.splice(array.length, 0, '๐Ÿด');
array[array.length] = '๐Ÿด';

// Result
// ['๐ŸฆŠ', '๐Ÿด']

Non Mutative

This will create a new array and the original array remains unchanged.

const original = ['๐ŸฆŠ'];
let newArray;

newArray = original.concat('๐Ÿฆ„');
newArray = [...original, '๐Ÿฆ„'];

// Result
newArray; // ['๐ŸฆŠ', '๐Ÿฆ„']
original; // ['๐ŸฆŠ']

3 Ways to Append Item to Array (Mutative)

Let's look at the 3 ways we can push an item to an array. This will be the mutative way, meaning it will change the original array.

push

The simplest way to add items to the end of an array is to use push.

const zoo = ['๐ŸฆŠ', '๐Ÿฎ'];

zoo.push('๐Ÿง');

console.log(zoo); // ['๐ŸฆŠ', '๐Ÿฎ', '๐Ÿง']

Notice I said item*s* and not just item ๐Ÿ˜‰ Yup, you can push multiple items.

const zoo = ['๐ŸฆŠ', '๐Ÿฎ'];

zoo.push('๐Ÿง', '๐Ÿฆ', '๐Ÿค');

console.log(zoo); // ['๐ŸฆŠ', '๐Ÿฎ', '๐Ÿง', '๐Ÿฆ', '๐Ÿค']

But passing individual item is such a drag, luckily we can use the ES6's spread feature. This allows us to pass an array and then use the ... syntax to spread the item into individual arguments ๐Ÿ™Œ

const zoo = ['๐ŸฆŠ', '๐Ÿฎ'];
const birds = ['๐Ÿง', '๐Ÿฆ', '๐Ÿค'];

zoo.push(...birds);

console.log(zoo); // ['๐ŸฆŠ', '๐Ÿฎ', '๐Ÿง', '๐Ÿฆ', '๐Ÿค']

splice

At first glance, this method can seem super needy ๐Ÿ˜‚ because we're passing a bunch of arguments. That's because this method can add OR remove array items. Hence it requires us to give it a bit more info for it to do it's job. Let's look at the parameters it require

Parameters Parameter Name Definition
1 startIndex The index where you want to add/remove item
2 deleteCount The number of items you want to remove
3 items The number you want to add
(If you're removing, you can just leave this blank)
const zoo = ['๐ŸฆŠ', '๐Ÿฎ'];

zoo.splice(
  zoo.length, // We want add at the END of our array
  0, // We do NOT want to remove any item
  '๐Ÿง', '๐Ÿฆ', '๐Ÿค', // These are the items we want to add
);

console.log(zoo); // ['๐ŸฆŠ', '๐Ÿฎ', '๐Ÿง', '๐Ÿฆ', '๐Ÿค']

length

I think this is the most clever way of all the methods. It's one of the ways that never crossed my mind. So let's understand why this works.

Arrays in JavaScript are zero-index. So the first item has an index of 0.

const zoo = ['๐ŸฆŠ', '๐Ÿฎ'];

// '๐ŸฆŠ' | Index = 0
// '๐Ÿฎ' | Index = 1

The bracket notation in arrays allows us to retrieve the item BUT it can also let us override that item.

const zoo = ['๐ŸฆŠ', '๐Ÿฎ'];

// Retrieve
zoo[0]; // Returns '๐ŸฆŠ'

// Override
zoo[1] = '๐Ÿฅฉ';

console.log(zoo); // ['๐ŸฆŠ', '๐Ÿฅฉ']; **

// ** JUST JOKING ๐Ÿ˜‚
// ...I promise no animals were hurt in this blog post ๐Ÿ˜ฌ

The interesting thing is array.length returns us the total count of items in the array. That means the length is always one number higher than the last item of our index. So by assigning a value at the length index, it's essentially adding an item to the end of the array.

const zoo = ['๐ŸฆŠ', '๐Ÿฎ'];
const length = zoo.length; // 2

zoo[length] = '๐Ÿฏ';

console.log(zoo); // ['๐ŸฆŠ', '๐Ÿฎ', '๐Ÿฏ']

2 Ways to Append Item to Array (Non Mutative)

Alright, let's move on to appending an item to an array in a non-mutative way. Where the original array will remain un-touched and a new array will contain the addition.

concat

This method is meant to merge arrays. So we can use it to add multiple items by passing in an array.

const ocean = ['๐Ÿ™', '๐Ÿฆ€'];
const fish = ['๐Ÿ ', '๐ŸŸ']; // Array of multiple items

const aquarium = ocean.concat(fish);

aquarium; // ['๐Ÿ™', '๐Ÿฆ€', '๐Ÿ ', '๐ŸŸ']

// Original Array Not Affected
ocean; //  ['๐Ÿ™', '๐Ÿฆ€']

But it doesn't just accept arrays as its parameter, it also accept value(s).

const ocean = ['๐Ÿ™', '๐Ÿฆ€'];

const aquarium = ocean.concat('๐Ÿก'); // Add a single value
const sushi = ocean.concat('๐Ÿก', '๐Ÿš'); // Add multiple values

aquarium; // ['๐Ÿ™', '๐Ÿฆ€', '๐Ÿก']
sushi; //  ['๐Ÿ™', '๐Ÿฆ€', '๐Ÿก', '๐Ÿš']

// Original Array Not Affected
ocean; // ['๐Ÿ™', '๐Ÿฆ€']

spread

We can use the spread syntax to expand each array element into individual elements. A very popular application is to use spread to create a copy or merge two separate arrays. This is similar to the effects of concat.

const ocean = ['๐Ÿ™', '๐Ÿฆ€'];
const fish = ['๐Ÿ ', '๐ŸŸ'];

const aquarium = [...ocean, ...fish];

aquarium; // ['๐Ÿ™', '๐Ÿฆ€', '๐Ÿ ', '๐ŸŸ']

// Original Array Not Affected
ocean; //  ['๐Ÿ™', '๐Ÿฆ€']

However, if we didn't use spread, we will instead get a nested array, which is not what we want.

const ocean = ['๐Ÿ™', '๐Ÿฆ€'];
const fish = ['๐Ÿ ', '๐ŸŸ'];

const aquarium = [ocean, fish];

// [  ['๐Ÿ™', '๐Ÿฆ€'],  ['๐Ÿ ', '๐ŸŸ'] ]

So I can use it to merge arrays, but we can also pass the individual value(s), just like we do in creating a regular array.

const ocean = ['๐Ÿ™', '๐Ÿฆ€'];

const aquarium = [...ocean, '๐Ÿก']; // Add a single value
const sushi = [...ocean, '๐Ÿก', '๐Ÿš']; // Add multiple values

aquarium; // ['๐Ÿ™', '๐Ÿฆ€', '๐Ÿก']
sushi; //  ['๐Ÿ™', '๐Ÿฆ€', '๐Ÿก', '๐Ÿš']

// Original Array Not Affected
ocean; // ['๐Ÿ™', '๐Ÿฆ€']

To Mutate Or Not to Mutate?

So the question is, to mutate or not to mutate ๐ŸŽญ Well that really depends on your use case. When you're working in Redux or any state management architecture, then it's all about the immutability. So the non-mutative methods will be your choices. Also, the idea of immutability is often preferred as it's considered a good practice to avoid side effects -- which is the foundation of functional programming and producing pure functions.

But does that mean we should never use mutative methods? Not at all. Because there are times when immutability just doesn't matter. Take this simple example.

function menu(isFriday) {
  const food = ['๐Ÿ—', '๐Ÿณ'];
  isFriday ? food.push('๐Ÿท') : food;

  return food;
}

In these cases, why not use the mutative methods. My go-to for appending a value is push. Why? Because it's less typing (yes, I'm very lazy ๐Ÿ˜‚) and super readable. Yes, you can argue that concat is also very short to type. But check out this performance test. Push is lot faster! โšก๏ธ

Performance Test: Push vs Concat

Community Input

@DigianPaul: To Mutate or Not to Mutate? In general it is a very deep question. But, to simplify, suppose the original array is still needed somewhere else? Then you don't want to mutate it. If it is not needed, you can mutate it directly, which is usually faster than creating a copy.

Said there are data structures where creating a copied of the array is as cheap as mutate it (or comparable cheap) and those are very cool but not so widespread in the JavaScript community.

Those are called "Persistent data structures" and are extremely useful in a lot of cases. But they are quite complex to design.

They make simple to implement functionality like undo-redo for instance. But they really shine in functional programming and also in multithread applications.

@KClarkADSTech: Also you can prepend by using [ newEl, ...array] or array.unshift(newEl).

@stojakovic99: One hacky way to add an empty item to an array (if we can even call it appending an item to an array, I think more appropriate term would be resizing) would be: (However you should never ever do this.)

const array = [1, 2];

array.length = 3;

console.log(array); // [1, 2, <1 empty item>]

@devhammed: You can also use it to shrink array

const array = [1, 2];

array.length = 1;

console.log(array); // [1]

@johnkazer: The point about not mutating if you need the array elsewhere is a good one, especially for parallel or concurrent programming. Even in single threaded JavaScript you might have passed an array by reference and so mutate things unexpectedly. Generally I find non-mutation to be a more relaxing method!

Resources

Thanks for reading โค
Say Hello! Instagram | Twitter | SamanthaMing.com

Discussion (18)

pic
Editor guide
Collapse
aleksandrhovhannisyan profile image
Aleksandr Hovhannisyan
const array = ['๐ŸฆŠ'];

array.push('๐Ÿด');
array.splice(array.length, 0, '๐Ÿด');
array[array.length] = '๐Ÿด';

// Result
// ['๐ŸฆŠ', '๐Ÿด']

What's the point of these two lines?

array.splice(array.length, 0, '๐Ÿด');
array[array.length] = '๐Ÿด';

Pretty sure array.push('๐Ÿด'); already gets the job done.

Collapse
luisaugusto profile image
Luis Augusto • Edited

I think it is just showing that there are three ways to make a mutative change to an array, each line does the same thing.

array.push('๐Ÿด') simply adds to the end of the array
array.splice(array.length, 0, '๐Ÿด') removes 0 items from the end of the array, and adds one item
array[array.length] = '๐Ÿด' adds an item to a specific position, which in this case is at the end of the array

Collapse
samanthaming profile image
Samantha Ming Author

yes, that's what I'm trying to do, thanks for clarifying Luis!

Aleksandr, I see how's that can be confusing...maybe i should fix it up ๐Ÿค”

Thread Thread
aleksandrhovhannisyan profile image
Aleksandr Hovhannisyan

Ah, yep, I thought it was all being executed sequentially

Collapse
stojakovic99 profile image
Nikola Stojakoviฤ‡

Great article!

Something for beginners (I'm pretty sure you already knew about this):

One hacky way to add an empty item to an array (if we can even call it appending an item to an array, I think more appropriate term would be resizing) would be:

const array = [1, 2];

array.length = 3;

console.log(array); // [1, 2, <1 empty item>]

However you should never ever do this.

Collapse
samanthaming profile image
Samantha Ming Author

Yes! Good one, let me add it to my notes ๐Ÿ’ช Thanks for sharing ๐Ÿ˜€

Collapse
devhammed profile image
Hammed Oyedele

You can also use it to shrink array

const array = [1, 2]

array.length = 1

console.log(array) // [1]
Thread Thread
samanthaming profile image
Samantha Ming Author

WOOO! never thought of that! Adding to my notes!!! thanks for sharing ๐Ÿ˜

Collapse
johnkazer profile image
John Kazer

The point about not mutating if you need the array elsewhere is a good one, especially for parallel or concurrent programming. Even in single threaded JavaScript you might have passed an array by reference and so mutate things unexpectedly. Generally I find non-mutation to be a more relaxing method!

Collapse
samanthaming profile image
Samantha Ming Author

Yes, great point John! Let me add that to my notes! Thanks for sharing ๐Ÿ‘

Collapse
zuchers profile image
zuchers

great post, keep going

Collapse
samanthaming profile image
Samantha Ming Author

You bet! Thanks for the encouragement! ๐Ÿ™Œ

Collapse
delta456 profile image
Swastik Baranwal

Nice article!

Collapse
samanthaming profile image
Samantha Ming Author

Thanks! Glad you found it helpful ๐Ÿ™‚

Collapse
maniekm profile image
Mariusz

Great stuff, thanks for sharing!

Collapse
samanthaming profile image
Samantha Ming Author

You're welcome! Thanks for reading my article ๐Ÿ™‚

Collapse
rafaacioly profile image
Rafael Acioly

Great post :)

Every time i read a post with "X ways to do something" i remember when i started to learn Golang then i start laughing.

Collapse
samanthaming profile image
Samantha Ming Author

Do say more, what's Golang like? ๐Ÿ˜ƒ