Home JavaScript JavaScript Arrays Explained: Creation, Access, and Common Mistakes

JavaScript Arrays Explained: Creation, Access, and Common Mistakes

In Plain English 🔥
Think of an array like a numbered egg carton. Each slot holds one egg (a value), and every slot has a number printed on it starting from zero — so the first egg is in slot 0, the second in slot 1, and so on. Instead of reaching into a random carton and guessing where the eggs are, you can say 'give me the egg in slot 2' and get exactly what you asked for. That is all an array is: an ordered list of things, where every item has a numbered address.
⚡ Quick Answer
Think of an array like a numbered egg carton. Each slot holds one egg (a value), and every slot has a number printed on it starting from zero — so the first egg is in slot 0, the second in slot 1, and so on. Instead of reaching into a random carton and guessing where the eggs are, you can say 'give me the egg in slot 2' and get exactly what you asked for. That is all an array is: an ordered list of things, where every item has a numbered address.

Every app you use daily — your music player, your shopping cart, your Instagram feed — is secretly just lists of things displayed in a particular order. A playlist is a list of songs. A cart is a list of products. A feed is a list of posts. JavaScript needs a way to store and manage those lists, and that is exactly what arrays do. Without arrays, you would have to create a separate variable for every single item — imagine writing song1, song2, song3 all the way to song500. That is not programming, that is torture.

Arrays solve the 'I have many related things and I need to work with them together' problem. They let you store an unlimited number of values under one variable name, access any item instantly by its position, add or remove items on the fly, and loop through every item without writing repetitive code. They are the single most used data structure in JavaScript, and you will reach for them constantly.

By the end of this article you will know how to create an array, read and change its values, add and remove items, loop through every element, and avoid the three mistakes that trip up almost every beginner. You will also know the answers to the array questions that show up in almost every junior JavaScript interview.

Creating an Array and Reading Values From It

You create an array using square brackets [] with values separated by commas. That is the whole syntax. The values inside are called elements, and they can be any type — numbers, strings, booleans, even other arrays.

The critical thing to burn into your memory right now: arrays in JavaScript are zero-indexed. The first item lives at position 0, not position 1. This trips up every beginner at least once. Think of it like floors in a European building — the ground floor is floor 0, the next one up is floor 1.

To read a specific element you write the array name followed by the index (position number) inside square brackets — myArray[0] gives you the first item. You can also check how many items are in an array using the .length property, which always tells you the actual count (not the last index — that is always length - 1).

Arrays can hold mixed types, but in practice you will almost always store the same kind of data in one array. A list of usernames, a list of prices, a list of temperatures — keeping things consistent makes your code far easier to reason about.

creatingAndReadingArrays.js · JAVASCRIPT
123456789101112131415161718192021
// Create an array of fruit names using square bracket syntax
const shoppingBasket = ['apple', 'banana', 'cherry', 'mango', 'kiwi'];

// Arrays are ZERO-indexed — the first item is at index 0, not 1
console.log(shoppingBasket[0]); // 'apple'  — first item
console.log(shoppingBasket[1]); // 'banana' — second item
console.log(shoppingBasket[4]); // 'kiwi'   — fifth (last) item

// .length tells you how many items are in the array
console.log(shoppingBasket.length); // 5

// The LAST item is always at index: length - 1
// This works even if you don't know how long the array is
console.log(shoppingBasket[shoppingBasket.length - 1]); // 'kiwi'

// What happens if you ask for an index that doesn't exist?
console.log(shoppingBasket[10]); // undefined — no crash, just undefined

// Arrays can hold mixed types (though you'll rarely need this)
const mixedBag = ['hello', 42, true, null];
console.log(mixedBag[2]); // true
▶ Output
apple
banana
kiwi
5
kiwi
undefined
true
⚠️
Watch Out: Zero-Indexing Bites Everyone OnceIf your array has 5 items, the valid indexes are 0, 1, 2, 3, and 4. Index 5 does not exist — you get `undefined`. Always use `array[array.length - 1]` to safely grab the last item regardless of array size.

Changing, Adding, and Removing Items in an Array

An array is not read-only — you can update existing items, push new ones onto the end, or remove items from either end. This is where arrays start to feel alive.

To update an item, simply assign a new value to its index: basket[0] = 'grape' replaces whatever was at position 0 with 'grape'. The array length stays the same.

To add items to the end of an array, use .push(). It is the most common way to grow an array — think of it like tossing something into the back of a queue. You can push one item or several at once.

To remove the last item, use .pop(). It does two things: removes the last element AND returns it, so you can store it if you need it.

For the front of the array: .unshift() adds to the beginning (everything shifts right), and .shift() removes the first item. These are slower on large arrays because every other element has to be re-indexed, but for small arrays you will never notice.

Finally, .splice() is your power tool — it can remove items from any position, insert items anywhere, or do both at once. It is worth knowing, but push and pop will cover 80% of your real-world needs.

modifyingArrays.js · JAVASCRIPT
12345678910111213141516171819202122232425262728293031323334
const taskList = ['write tests', 'fix bug', 'deploy app'];
console.log('Original:', taskList);

// UPDATE — change an existing item by its index
taskList[1] = 'fix critical bug'; // replace item at index 1
console.log('After update:', taskList);

// PUSH — add a new item to the END of the array
taskList.push('send release notes');
console.log('After push:', taskList);

// POP — remove and RETURN the last item
const completedTask = taskList.pop(); // removes 'send release notes'
console.log('Removed task:', completedTask);
console.log('After pop:', taskList);

// UNSHIFT — add an item to the FRONT (everything shifts right)
taskList.unshift('review PR');
console.log('After unshift:', taskList);

// SHIFT — remove and return the FIRST item
const firstTask = taskList.shift();
console.log('Removed from front:', firstTask);
console.log('After shift:', taskList);

// SPLICE — remove 1 item starting at index 1
// Arguments: (startIndex, deleteCount)
taskList.splice(1, 1); // removes 'fix critical bug'
console.log('After splice:', taskList);

// SPLICE to INSERT — add without removing
// Arguments: (startIndex, 0, itemToInsert)
taskList.splice(1, 0, 'write changelog');
console.log('After splice insert:', taskList);
▶ Output
Original: [ 'write tests', 'fix bug', 'deploy app' ]
After update: [ 'write tests', 'fix critical bug', 'deploy app' ]
After push: [ 'write tests', 'fix critical bug', 'deploy app', 'send release notes' ]
Removed task: send release notes
After pop: [ 'write tests', 'fix critical bug', 'deploy app' ]
After unshift: [ 'review PR', 'write tests', 'fix critical bug', 'deploy app' ]
Removed from front: review PR
After shift: [ 'write tests', 'fix critical bug', 'deploy app' ]
After splice: [ 'write tests', 'deploy app' ]
After splice insert: [ 'write tests', 'write changelog', 'deploy app' ]
⚠️
Pro Tip: push/pop vs shift/unshift Performance`.push()` and `.pop()` only touch the end of the array — O(1) speed. `.shift()` and `.unshift()` re-index every element — O(n) speed. For large arrays (thousands of items), prefer working with the end of the array whenever you can.

Looping Through Every Item in an Array

Storing data in an array is only half the job — you almost always need to do something with every item. Looping is how you walk through an array element by element.

The classic for loop gives you full control: you start at index 0, keep going while the index is less than the array length, and increment by 1 each time. It is verbose but reliable, and it is perfect when you need the index number alongside the value.

The for...of loop is cleaner and more readable when you only care about the values themselves — you never touch an index number. This is the one you will use most often for reading and processing items.

The .forEach() method is the array's own built-in loop. You pass it a function, and it calls that function once per element, handing you the current item, its index, and the full array. It is great for readability.

Think of for...of as your daily driver and the classic for loop as your four-wheel-drive for when terrain gets tricky (needing the index, breaking early, counting backwards).

One thing to know now and revisit later: .map(), .filter(), and .reduce() are higher-order array methods that transform arrays rather than just reading them — they are the next level after loops and absolutely worth learning once this clicks.

loopingThroughArrays.js · JAVASCRIPT
12345678910111213141516171819202122232425262728293031323334
const temperatures = [22, 17, 30, 25, 19, 28];

// METHOD 1: Classic for loop — use when you need the index
console.log('--- Classic for loop ---');
for (let index = 0; index < temperatures.length; index++) {
  // index goes 0, 1, 2 ... up to (length - 1)
  console.log(`Day ${index + 1}: ${temperatures[index]}°C`);
}

// METHOD 2: for...of — cleanest syntax when you just need the value
console.log('\n--- for...of loop ---');
for (const temp of temperatures) {
  // 'temp' holds the actual value, not the index
  if (temp >= 25) {
    console.log(`${temp}°C — hot day!`);
  } else {
    console.log(`${temp}°C — mild day.`);
  }
}

// METHOD 3: forEach — array's own built-in loop
console.log('\n--- forEach ---');
temperatures.forEach((temp, index) => {
  // forEach hands you: (currentValue, currentIndex, theWholeArray)
  console.log(`Index ${index} → ${temp}°C`);
});

// PRACTICAL EXAMPLE: Calculate the average temperature
let total = 0;
for (const temp of temperatures) {
  total += temp; // add each temperature to the running total
}
const average = total / temperatures.length;
console.log(`\nAverage temperature: ${average.toFixed(1)}°C`);
▶ Output
--- Classic for loop ---
Day 1: 22°C
Day 2: 17°C
Day 3: 30°C
Day 4: 25°C
Day 5: 19°C
Day 6: 28°C

--- for...of loop ---
22°C — mild day.
17°C — mild day.
30°C — hot day!
25°C — hot day!
19°C — mild day.
28°C — hot day!

--- forEach ---
Index 0 → 22°C
Index 1 → 17°C
Index 2 → 30°C
Index 3 → 25°C
Index 4 → 19°C
Index 5 → 28°C

Average temperature: 23.5°C
🔥
Interview Gold: Which Loop Should You Use?Use `for...of` when you only need values. Use a classic `for` loop when you need the index or want to break early with `break`. Use `.forEach()` when passing a reusable callback function. Interviewers love this question — now you have a real answer.

Searching and Transforming Arrays with Built-In Methods

JavaScript ships with a rich set of array methods that handle the most common tasks you will face — finding an item, checking if something exists, building a new array from an old one, or filtering down to only the items you care about. These methods save you from writing repetitive loop code.

.includes() answers the yes/no question: 'does this array contain this value?' It returns true or false.

.indexOf() goes further: it tells you the exact index where a value lives, or -1 if it is not found. The -1 return value is a JavaScript convention you will see everywhere.

.find() lets you search by a condition rather than an exact value. You give it a function that returns true when it finds a match, and it hands you back the actual element.

.map() creates a brand new array by transforming every element. The original array is never touched. Think of it as a factory conveyor belt — every item goes in, gets processed, and a new version comes out.

.filter() creates a new array containing only the items that pass a test. Think of it as a sieve — only items where your condition returns true make it through.

These five methods alone — includes, indexOf, find, map, and filter — will handle the vast majority of array work you do in real JavaScript projects.

arrayMethods.js · JAVASCRIPT
1234567891011121314151617181920212223242526272829303132333435363738394041
const productPrices = [
  { name: 'keyboard', price: 79 },
  { name: 'mouse',    price: 35 },
  { name: 'monitor',  price: 299 },
  { name: 'webcam',   price: 89 },
  { name: 'headset',  price: 149 },
];

const productNames = ['keyboard', 'mouse', 'monitor', 'webcam', 'headset'];

// INCLUDES — does this array contain 'monitor'?
console.log(productNames.includes('monitor')); // true
console.log(productNames.includes('tablet'));  // false

// INDEXOF — at what position is 'webcam'?
const webcamPosition = productNames.indexOf('webcam');
console.log(`webcam is at index: ${webcamPosition}`); // 3
console.log(productNames.indexOf('tablet')); // -1 means NOT FOUND

// FIND — give me the first product object where price > 100
const firstExpensiveProduct = productPrices.find(
  (product) => product.price > 100 // this runs once per item until true
);
console.log('First expensive product:', firstExpensiveProduct);

// MAP — create a NEW array of just the names (original untouched)
const namesOnly = productPrices.map((product) => product.name);
console.log('Names only:', namesOnly);

// MAP — apply a 10% discount to every price, return new array
const discountedPrices = productPrices.map((product) => ({
  name: product.name,
  price: +(product.price * 0.9).toFixed(2), // + converts string back to number
}));
console.log('Discounted prices:', discountedPrices);

// FILTER — only keep products under £100
const affordableProducts = productPrices.filter(
  (product) => product.price < 100
);
console.log('Affordable products:', affordableProducts);
▶ Output
true
false
webcam is at index: 3
-1
First expensive product: { name: 'monitor', price: 299 }
Names only: [ 'keyboard', 'mouse', 'monitor', 'webcam', 'headset' ]
Discounted prices: [
{ name: 'keyboard', price: 71.1 },
{ name: 'mouse', price: 31.5 },
{ name: 'monitor', price: 269.1 },
{ name: 'webcam', price: 80.1 },
{ name: 'headset', price: 134.1 }
]
Affordable products: [
{ name: 'keyboard', price: 79 },
{ name: 'mouse', price: 35 },
{ name: 'webcam', price: 89 }
]
⚠️
Pro Tip: map and filter Never Modify the Original`.map()` and `.filter()` always return brand-new arrays — the original array stays unchanged. This is called immutability, and it prevents a whole category of bugs. If your original data changed unexpectedly after using these methods, you are probably using `.forEach()` and mutating manually instead.
MethodWhat It ReturnsModifies Original?Best Used For
.push(item)New array lengthYesAdding an item to the end
.pop()The removed itemYesRemoving the last item
.map(fn)New transformed arrayNoTransforming every element
.filter(fn)New filtered arrayNoKeeping only matching items
.find(fn)First matching element or undefinedNoGetting one item by condition
.includes(val)true or falseNoChecking if a value exists
.indexOf(val)Index number or -1NoFinding a value's position
.splice(i, n)Array of removed itemsYesRemoving/inserting at any index

🎯 Key Takeaways

  • JavaScript arrays are zero-indexed — the first item is always at index 0, and the last item is always at index array.length - 1, never at array.length.
  • .push() and .pop() modify the original array; .map() and .filter() always return a brand-new array and never touch the original — this distinction matters enormously in real projects.
  • Use for...of when you only need values, a classic for loop when you need the index number or want to break out early, and .forEach() when passing a named callback function.
  • Getting undefined when reading an array element means you asked for an index that does not exist — it is not a crash, but it is a signal your index logic is off by one or your array is shorter than you expected.

⚠ Common Mistakes to Avoid

  • Mistake 1: Using index 1 to access the first element instead of index 0 — Symptom: you get the second item instead of the first, or undefined when accessing array[array.length] — Fix: always remember arrays start at 0; the first item is array[0] and the last is array[array.length - 1].
  • Mistake 2: Expecting .push() to return the new array instead of the new length — Symptom: you write const updated = myArray.push('newItem') and then wonder why updated is a number like 4, not an array — Fix: .push() mutates the original array in place and returns the new length; just call myArray.push('newItem') and continue using myArray directly.
  • Mistake 3: Using const and assuming the array can never change — Symptom: you declare const colors = ['red', 'blue'], then try .push('green') and are surprised it works, or you incorrectly think const means the array is locked — Fix: const only prevents you from reassigning the variable to a completely different value; the array's contents can still be modified freely. To truly freeze an array, use Object.freeze(colors).

Interview Questions on This Topic

  • QWhat is the difference between `.map()` and `.forEach()` in JavaScript, and when would you choose one over the other?
  • QIf I have an array of 100 user objects and I want to get a new array containing only users who are over 18 and have verified their email, how would you approach that in one readable line?
  • QWhat does `.splice()` return, and how is it different from `.slice()`? — This one catches people out because the names sound almost identical but they behave completely differently.

Frequently Asked Questions

Can a JavaScript array hold different types of values like numbers and strings together?

Yes — JavaScript arrays can hold any mix of types including numbers, strings, booleans, objects, and even other arrays. That said, mixing types in a single array is usually a sign of a design problem. In practice, keep one array focused on one kind of data to make your code predictable and easy to debug.

What is the difference between JavaScript array `.slice()` and `.splice()`?

.slice(start, end) returns a new array copied from the original between two indexes — it never modifies the original. .splice(start, deleteCount) modifies the original array by removing or inserting items in place and returns the removed items. If you want a safe copy of a portion, use .slice(). If you want to actually change the array, use .splice().

Why do I get `undefined` when I try to read an array element?

You are accessing an index that does not exist in the array. The most common causes are: reading index array.length instead of array.length - 1 (off-by-one error), or the array is empty. JavaScript does not throw an error for out-of-bounds access — it silently returns undefined. Always double-check your index logic and verify the array has items before accessing them.

🔥
TheCodeForge Editorial Team Verified Author

Written and reviewed by senior developers with real-world experience across enterprise, startup and open-source projects. Every article on TheCodeForge is written to be clear, accurate and genuinely useful — not just SEO filler.

← PreviousFunctions in JavaScriptNext →Objects in JavaScript
Forged with 🔥 at TheCodeForge.io — Where Developers Are Forged