Master JavaScript arrays from scratch. Learn array creation, indexing, iteration, multidimensional arrays, reference types, and memory behavior with 30+ examples.
What is an Array?
An array is an ordered collection of values stored in a single variable. Arrays in JavaScript are dynamic, meaning they can grow or shrink in size, and they can hold values of any type — numbers, strings, objects, functions, or even other arrays.
Arrays are reference types in JavaScript. When you assign an array to a variable, you store a reference (memory address) to the array, not the array itself.
Visual: Array in Memory
Variable: fruits
┌─────────────────────────────────────────┐
│ Index: [0] [1] [2] │
│ Value: "Apple" "Banana" "Cherry" │
└─────────────────────────────────────────┘
// Arrays store multiple values in one variable
const fruits = ["Apple", "Banana", "Cherry"];
console.log(fruits);
console.log(typeof fruits);
console.log(Array.isArray(fruits));
["Apple", "Banana", "Cherry"]
"object"
true
Accessing Array Elements
Indexing (Zero-Based)
Arrays use zero-based indexing — the first element is at index 0:
const colors = ["Red", "Green", "Blue", "Yellow"];
console.log(colors[0]);
// "Red"
console.log(colors[2]);
// "Blue"
console.log(colors[colors.length - 1]);
// "Yellow"
// Accessing non-existent index
console.log(colors[10]);
// undefined
"Red"
"Blue"
"Yellow"
undefined
Array.at() Method (ES2022)
Supports negative indexing:
const arr = [10, 20, 30, 40, 50];
console.log(arr.at(0));
// 10
console.log(arr.at(-1));
// 50
console.log(arr.at(-2));
// 40
Visual: Positive vs Negative Indexing
Array: [10, 20, 30, 40, 50]
Positive: [0] [1] [2] [3] [4]
Negative: [-5] [-4] [-3] [-2] [-1]
Array Length Property
The length property returns the number of elements:
const items = ["a", "b", "c", "d"];
console.log(items.length);
// 4
// Length is writable - can truncate array
items.length = 2;
console.log(items);
// ["a", "b"]
// Can extend array (creates empty slots)
items.length = 5;
console.log(items);
// ["a", "b", empty × 3]
4
["a", "b"]
["a", "b", empty × 3]
Length vs Last Index
const arr = [10, 20, 30];
console.log("Length:", arr.length);
// Length: 3
console.log("Last index:", arr.length - 1);
// Last index: 2
console.log("Last element:", arr[arr.length - 1]);
// Last element: 30
Length: 3
Last index: 2
Last element: 30
Modifying Array Elements
const languages = ["JavaScript", "Python", "Java"];
// Change element at index
languages[1] = "TypeScript";
console.log(languages);
// ["JavaScript", "TypeScript", "Java"]
// Add element at specific index
languages[3] = "Rust";
console.log(languages);
// ["JavaScript", "TypeScript", "Java", "Rust"]
// ⚠️ Adding at non-consecutive index creates holes
languages[10] = "Go";
console.log(languages.length);
// 11
console.log(languages[5]);
// undefined
["JavaScript", "TypeScript", "Java"]
["JavaScript", "TypeScript", "Java", "Rust"]
11
undefined
Checking if Something is an Array
console.log(Array.isArray([1, 2, 3]));
// true
console.log(Array.isArray("hello"));
// false
console.log(Array.isArray({ length: 3 }));
// false
console.log(Array.isArray(new Array()));
// true
// typeof returns "object" for arrays - unreliable!
console.log(typeof [1, 2, 3]);
// "object"
true
false
false
true
"object"
Iterating Over Arrays
for Loop
const fruits = ["Apple", "Banana", "Cherry"];
for (let i = 0; i < fruits.length; i++) {
console.log(`${i}: ${fruits[i]}`);
}
0: Apple
1: Banana
2: Cherry
for...of Loop (✅ Modern Recommended)
const numbers = [10, 20, 30];
for (const num of numbers) {
console.log(num);
}
for...in Loop (❌ Not Recommended for Arrays)
const arr = [1, 2, 3];
for (const index in arr) {
console.log(index, typeof index);
}
// Note: for...in gives STRING indices and iterates over ALL enumerable properties
0 string
1 string
2 string
forEach Method
const colors = ["Red", "Green", "Blue"];
colors.forEach((color, index) => {
console.log(`${index + 1}. ${color}`);
});
entries() — Index + Value Together
const langs = ["HTML", "CSS", "JavaScript"];
for (const [index, lang] of langs.entries()) {
console.log(`${index}: ${lang}`);
}
0: HTML
1: CSS
2: JavaScript
Multidimensional Arrays
2D Arrays (Matrix)
const matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
console.log(matrix[0][0]);
// 1
console.log(matrix[1][2]);
// 6
console.log(matrix[2][1]);
// 8
// Iterate over 2D array
for (let i = 0; i < matrix.length; i++) {
let row = "";
for (let j = 0; j < matrix[i].length; j++) {
row += matrix[i][j] + " ";
}
console.log(row.trim());
}
Visual: 2D Array
col0 col1 col2
row 0 [ 1, 2, 3 ]
row 1 [ 4, 5, 6 ] ← matrix[1][2] = 6
row 2 [ 7, 8, 9 ]
3D Arrays
const cube = [
[[1, 2], [3, 4]],
[[5, 6], [7, 8]]
];
console.log(cube[0][1][0]);
// 3
console.log(cube[1][0][1]);
// 6
Array of Objects
const students = [
{ name: "Alice", age: 22, grade: "A" },
{ name: "Bob", age: 21, grade: "B" },
{ name: "Charlie", age: 23, grade: "A" }
];
// Access object property in array
console.log(students[0].name);
// "Alice"
console.log(students[1].grade);
// "B"
// Find student by name
const bob = students.find(s => s.name === "Bob");
console.log(bob);
// {name: "Bob", age: 21, grade: "B"}
"Alice"
"B"
{name: "Bob", age: 21, grade: "B"}
Sparse Arrays and Holes
// Sparse array (has empty slots)
const sparse = [1, , , 4];
console.log(sparse.length);
// 4
console.log(sparse[1]);
// undefined
// Check if index exists
console.log(1 in sparse);
// false
console.log(0 in sparse);
// true
// forEach skips holes
sparse.forEach((val, i) => console.log(i, val));
4
undefined
false
true
0 1
3 4
Array Reference Behavior
// Arrays are reference types
const a = [1, 2, 3];
const b = a; // b points to same array
b.push(4);
console.log(a);
// [1, 2, 3, 4] — a is also modified!
// Create a true shallow copy
const c = [...a];
c.push(5);
console.log(a);
// [1, 2, 3, 4] — a is NOT modified
console.log(c);
// [1, 2, 3, 4, 5]
[1, 2, 3, 4]
[1, 2, 3, 4]
[1, 2, 3, 4, 5]
Memory Diagram: Reference vs Copy
const a ──────────────► [ 1, 2, 3 ]
const b = a ────────────────↑ (same pointer)
const c = [...a] ───────► [ 1, 2, 3 ] (new memory)
Comparing Arrays
const x = [1, 2, 3];
const y = [1, 2, 3];
console.log(x === y);
// false (different references)
// Compare by content
console.log(JSON.stringify(x) === JSON.stringify(y));
// true
Passing Arrays to Functions
function doubleAll(arr) {
for (let i = 0; i < arr.length; i++) {
arr[i] *= 2;
}
}
const nums = [1, 2, 3, 4];
doubleAll(nums);
console.log(nums);
// [2, 4, 6, 8] — Original array is modified!
// Safe: create new array instead
function safeDouble(arr) {
return arr.map(n => n * 2);
}
const original = [1, 2, 3];
const doubled = safeDouble(original);
console.log(original);
// [1, 2, 3] — unchanged
console.log(doubled);
// [2, 4, 6]
[2, 4, 6, 8]
[1, 2, 3]
[2, 4, 6]
- Pre-allocate when possible:
new Array(1000) is faster than pushing 1000 times - Avoid sparse arrays: Dense arrays are optimized by V8 engine
- Use typed arrays for numeric data:
Float64Array, Int32Array for performance-critical code - Cache array length in loops:
const len = arr.length before the loop - Prefer
for loops for performance: for is faster than forEach in tight loops - Avoid
delete on arrays: Creates holes, use splice instead
// ❌ Slow: delete creates holes
const arr = [1, 2, 3, 4, 5];
delete arr[2];
console.log(arr);
// [1, 2, empty, 4, 5]
// ✅ Correct: splice removes cleanly
const arr2 = [1, 2, 3, 4, 5];
arr2.splice(2, 1);
console.log(arr2);
// [1, 2, 4, 5]
[1, 2, empty, 4, 5]
[1, 2, 4, 5]
Real World Use Cases
// 1. Shopping cart
const cart = [];
cart.push({ name: "Laptop", price: 80000 });
cart.push({ name: "Mouse", price: 500 });
const total = cart.reduce((sum, item) => sum + item.price, 0);
console.log(`Cart: ${cart.length} items, Total: ₹${total}`);
// 2. Student gradebook
const scores = [78, 92, 65, 88, 95];
const avg = scores.reduce((s, n) => s + n, 0) / scores.length;
const passing = scores.filter(s => s >= 70);
console.log(`Average: ${avg}, Passing: ${passing.length}`);
// 3. Unique tags
const tags = ["js", "css", "js", "html", "css", "js"];
const uniqueTags = [...new Set(tags)];
console.log("Unique tags:", uniqueTags);
// 4. Menu list
const menu = ["Home", "About", "Services", "Contact"];
const navLinks = menu.map((item, i) => `${i + 1}. ${item}`);
navLinks.forEach(link => console.log(link));
Cart: 2 items, Total: ₹80500
Average: 83.6, Passing: 4
Unique tags: ["js", "css", "html"]
1. Home
2. About
3. Services
4. Contact
Common Mistakes
| ❌ Wrong | ✅ Correct | Why |
|---|
new Array(5) when wanting [5] | Array.of(5) or [5] | Constructor treats single number as length |
const b = a for a copy | const b = [...a] | Assignment copies the reference |
arr[arr.length] for last element | arr[arr.length - 1] or arr.at(-1) | Length is one more than last index |
delete arr[i] to remove | arr.splice(i, 1) | delete leaves a hole |
typeof arr === "array" | Array.isArray(arr) | typeof [] returns "object" |
for...in on arrays | for...of or forEach | for...in iterates keys as strings and includes prototype |
Cheat Sheet
Create: const arr = [1, 2, 3]
Access: arr[0] → first element
Last element: arr[arr.length - 1] or arr.at(-1)
Length: arr.length
Add to end: arr.push(value)
Remove end: arr.pop()
Add to front: arr.unshift(value)
Remove front: arr.shift()
Shallow copy: [...arr] or arr.slice()
Deep copy: structuredClone(arr)
Check type: Array.isArray(arr) → true
Iterate: for (const item of arr) {}
Convert set: [...new Set(arr)] → deduplicated
Interview Questions
Q1. What is an array in JavaScript and how does it differ from an object?
An array is an ordered, zero-indexed collection. Objects use string keys; arrays use numeric indices. Internally, arrays are objects — typeof [] === "object" — but Array.isArray([]) returns true. Arrays also inherit special methods like push, pop, map, etc.
Q2. What is the difference between const a = arr and const a = [...arr]?
const a = arr copies the reference — both variables point to the same array in memory. const a = [...arr] creates a new shallow copy with the same values.
Q3. Why does new Array(5) create empty slots instead of [5]?
When new Array() receives a single numeric argument, it treats it as the desired length, not an element. Use Array.of(5) or [5].
Q4. What is zero-based indexing?
Arrays start counting from 0. First element = arr[0], last = arr[arr.length - 1] or arr.at(-1).
Q5. What is a sparse array?
A sparse array has "holes" — missing indices. Created by delete arr[i], arr.length = bigNumber, or [1,,3] syntax. Methods like forEach skip holes.
Q6. How do you check if a variable is an array?
Use Array.isArray(variable). Never use typeof — it returns "object" for arrays.
Q7. Can arrays hold different data types?
Yes. JavaScript arrays are heterogeneous — they can hold any mix of types in the same array.
Q8. What is the difference between for...of and for...in for arrays?
for...of iterates over the values — the clean, recommended way. for...in iterates over the string keys (including any inherited enumerable properties) — unreliable for arrays.
Key Takeaways
- Arrays are ordered, zero-indexed, dynamic collections of any type
- Use
[] literals — avoid new Array() to prevent the length gotcha - Arrays are reference types —
= assignment copies the pointer, not the data - Use
Array.isArray() to type-check arrays - Use
arr.at(-1) for the last element (ES2022+) delete leaves holes — use splice() to properly remove elementsfor...of is the cleanest loop for arrays