What Are Arrays?
Imagine you have a shopping list. Instead of writing separate variables for each item, arrays let you store multiple values in a single, organized container. Arrays are like a train with multiple cars, where each car holds a different piece of data.
Creating Arrays
Just like there are different ways to make a sandwich, there are multiple ways to create arrays in JavaScript:
// Method 1: Array literal (most common)
const fruits = ['apple', 'banana', 'orange'];
// Method 2: Array constructor
const numbers = new Array(1, 2, 3, 4, 5);
// Method 3: Empty array
const emptyBasket = [];
// Arrays can hold mixed data types
const mixedBag = ['text', 42, true, null, { name: 'John' }];
Real-World Example: Shopping Cart
// A shopping cart in an e-commerce site
const shoppingCart = [
{ product: 'Laptop', price: 999.99, quantity: 1 },
{ product: 'Mouse', price: 29.99, quantity: 2 },
{ product: 'Keyboard', price: 89.99, quantity: 1 }
];
Array Properties and Access
Arrays are like apartment buildings - each item has its own "apartment number" (index), starting from 0:
const colors = ['red', 'green', 'blue', 'yellow'];
// Accessing elements
console.log(colors[0]); // 'red' (first element)
console.log(colors[2]); // 'blue' (third element)
// Length property - like counting floors in a building
console.log(colors.length); // 4
// Modifying elements - like repainting an apartment
colors[1] = 'lime';
console.log(colors); // ['red', 'lime', 'blue', 'yellow']
// Accessing last element
console.log(colors[colors.length - 1]); // 'yellow'
Essential Array Methods
Arrays come with built-in superpowers (methods) that help you manipulate data:
Push and Pop - Adding/Removing from the End
const playlist = ['Song A', 'Song B'];
// push() - Like adding songs to end of playlist
playlist.push('Song C');
console.log(playlist); // ['Song A', 'Song B', 'Song C']
// pop() - Like removing the last song
const lastSong = playlist.pop();
console.log(lastSong); // 'Song C'
console.log(playlist); // ['Song A', 'Song B']
Unshift and Shift - Adding/Removing from the Start
const queue = ['Person 2', 'Person 3'];
// unshift() - Like someone cutting in line
queue.unshift('Person 1');
console.log(queue); // ['Person 1', 'Person 2', 'Person 3']
// shift() - Like the first person being served
const firstPerson = queue.shift();
console.log(firstPerson); // 'Person 1'
console.log(queue); // ['Person 2', 'Person 3']
Finding Elements in Arrays
Finding items in arrays is like searching for a book in a library:
const books = ['JavaScript', 'Python', 'Java', 'C++', 'Python'];
// indexOf() - Find first occurrence (like finding first copy of book)
console.log(books.indexOf('Python')); // 1
console.log(books.indexOf('Ruby')); // -1 (not found)
// lastIndexOf() - Find last occurrence
console.log(books.lastIndexOf('Python')); // 4
// includes() - Check if item exists (like asking "Do you have this book?")
console.log(books.includes('Java')); // true
console.log(books.includes('Go')); // false
Slice and Splice - Array Surgery
Think of arrays as cakes that you can cut and modify:
slice() - Taking a Piece Without Changing Original
const cake = ['layer1', 'layer2', 'layer3', 'layer4', 'layer5'];
// Get a slice (doesn't modify original)
const middlePiece = cake.slice(1, 4);
console.log(middlePiece); // ['layer2', 'layer3', 'layer4']
console.log(cake); // Original unchanged
splice() - Surgery on the Array
const ingredients = ['flour', 'sugar', 'eggs', 'butter', 'salt'];
// Remove 2 items starting at index 1
const removed = ingredients.splice(1, 2);
console.log(removed); // ['sugar', 'eggs']
console.log(ingredients); // ['flour', 'butter', 'salt']
// Add items at index 1
ingredients.splice(1, 0, 'milk', 'vanilla');
console.log(ingredients); // ['flour', 'milk', 'vanilla', 'butter', 'salt']
Real-World Applications
Todo List Application
let todoList = [];
function addTask(task) {
todoList.push({
id: Date.now(),
task: task,
completed: false,
createdAt: new Date()
});
}
function completeTask(id) {
const taskIndex = todoList.findIndex(task => task.id === id);
if (taskIndex !== -1) {
todoList[taskIndex].completed = true;
}
}
function removeTask(id) {
todoList = todoList.filter(task => task.id !== id);
}
// Usage
addTask('Learn JavaScript arrays');
addTask('Practice array methods');
console.log(todoList);
completeTask(todoList[0].id);
console.log(todoList);
Playlist Manager
class PlaylistManager {
constructor() {
this.playlist = [];
this.currentIndex = 0;
}
addSong(song) {
this.playlist.push(song);
}
removeSong(index) {
if (index >= 0 && index < this.playlist.length) {
this.playlist.splice(index, 1);
}
}
shuffle() {
// Fisher-Yates shuffle algorithm
for (let i = this.playlist.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[this.playlist[i], this.playlist[j]] = [this.playlist[j], this.playlist[i]];
}
}
getCurrentSong() {
return this.playlist[this.currentIndex];
}
nextSong() {
this.currentIndex = (this.currentIndex + 1) % this.playlist.length;
return this.getCurrentSong();
}
}
// Usage
const myPlaylist = new PlaylistManager();
myPlaylist.addSong({ title: 'Song 1', artist: 'Artist A' });
myPlaylist.addSong({ title: 'Song 2', artist: 'Artist B' });
console.log(myPlaylist.getCurrentSong());
Performance Tips
- Use const/let: Always declare arrays with const if you won't reassign the variable
- Avoid delete: Use splice() instead of delete to avoid sparse arrays
- Pre-allocate size: If you know the size, create arrays with that size
- Cache length: In loops, cache the array length for better performance
// Good performance practice
const bigArray = new Array(1000); // Pre-allocated
// Caching length in loops
for (let i = 0, len = bigArray.length; i < len; i++) {
// Process array elements
}
// Avoid sparse arrays
const sparse = [1, 2, 3];
delete sparse[1]; // Creates a hole - bad!
console.log(sparse); // [1, empty, 3]
// Better approach
const dense = [1, 2, 3];
dense.splice(1, 1); // Removes and shifts
console.log(dense); // [1, 3]
Practice Exercises
- Create a function that reverses an array without using the reverse() method
- Build a function that removes duplicate values from an array
- Create a function that finds the second largest number in an array
- Implement a function that rotates an array by n positions
Exercise Solutions (Try First!)
Click to see solutions
// 1. Reverse array without reverse()
function reverseArray(arr) {
const result = [];
for (let i = arr.length - 1; i >= 0; i--) {
result.push(arr[i]);
}
return result;
}
// 2. Remove duplicates
function removeDuplicates(arr) {
return [...new Set(arr)];
// or
// return arr.filter((item, index) => arr.indexOf(item) === index);
}
// 3. Find second largest
function secondLargest(arr) {
if (arr.length < 2) return null;
let first = -Infinity;
let second = -Infinity;
for (const num of arr) {
if (num > first) {
second = first;
first = num;
} else if (num > second && num < first) {
second = num;
}
}
return second === -Infinity ? null : second;
}
// 4. Rotate array
function rotateArray(arr, n) {
const len = arr.length;
n = n % len; // Handle n greater than length
return [...arr.slice(n), ...arr.slice(0, n)];
}
Common Pitfalls to Avoid
- Off-by-one errors: Remember arrays start at index 0
- Modifying while iterating: Can cause unexpected behavior
- Reference vs. Value: Arrays are reference types
- Sparse arrays: Avoid using delete on array elements
// Pitfall: Reference types
const original = [1, 2, 3];
const copy = original; // This is a reference, not a copy!
copy[0] = 99;
console.log(original); // [99, 2, 3] - Original is modified!
// Solution: Create actual copies
const actualCopy1 = [...original]; // Spread operator
const actualCopy2 = original.slice(); // slice method
const actualCopy3 = Array.from(original); // Array.from
Summary
Arrays are fundamental data structures in JavaScript that:
- Store ordered collections of data
- Use zero-based indexing
- Provide powerful built-in methods for manipulation
- Can contain any data type, including other arrays
- Are reference types (careful when copying!)
Next up: We'll explore object literals and how they complement arrays in JavaScript!