Chapter 9 of 28 · JavaScript for Beginners — Complete Free Tutorial

Arrays & Array Methods

Arrays are ordered lists — the workhorse data structure of JavaScript. Beyond indexing, the standard library gives you powerful iteration methods (map, filter, reduce, find…) that replace most hand-written loops. This chapter is the complete practical reference.

Creating and reading arrays

const colors = ['red', 'green', 'blue'];
console.log(colors[0]);      // → 'red'
console.log(colors.length);  // → 3
console.log(colors.at(-1));  // → 'blue' (negative indexes count from the end)

const nums = [10, 20, 30];
console.log(Array.isArray(nums));     // → true
console.log(typeof nums);             // → object

Arrays are zero-indexed, sparse-friendly objects with a length; they can hold mixed types, though one consistent type per array is far easier to work with.

Mutating methods

MethodDoesReturns
push(…items)Add to endnew length
pop()Remove from endremoved item
unshift(…items)Add to startnew length
shift()Remove from startremoved item
splice(i, n, …items)Remove/insert at index i (delete n)removed items
sort(fn)Sort in placesame array
reverse()Reverse in placesame array
const queue = ['a', 'b'];
queue.push('c');        // → ['a', 'b', 'c']
queue.shift();          // → 'a', queue = ['b', 'c']

const list = ['x', 'y', 'z'];
list.splice(1, 1);      // removes 'y' → ['x', 'z']

Non-mutating alternatives (prefer these)

const base = [1, 2, 3];

const with4 = [...base, 4];          // append (spread copy)
const dropped = base.slice(1);       // copy without first → [2, 3]
const removed  = base.toSpliced(0, 1); // non-mutating splice → [2, 3]
const reversed = [...base].reverse();  // copy first, then reverse
const sorted   = [...base].sort((a, b) => a - b);

Expected output: base never changes — original arrays stay intact, which prevents a whole family of “who mutated my data?” bugs.

The sort trap

console.log([10, 9, 100].sort());          // → [10, 100, 9] 😱
console.log([10, 9, 100].sort((a, b) => a - b));  // → [9, 10, 100] ✅

// strings descend
console.log(['b', 'C', 'a'].sort((a, b) => b.localeCompare(a)));
// → ['b', 'a', 'C']

Default sort converts to strings — always pass a comparator for numbers: (a, b) => a - b (ascending; reverse the subtraction for descending). Use localeCompare for human-language string ordering.

The iteration toolkit

forEach — do something with each item

['a', 'b'].forEach((item, i) => console.log(`${i}: ${item}`));
// → 0: a
// → 1: b

map — transform every item into a new array

const prices = [10, 20, 30];
const withTax = prices.map((p) => Math.round(p * 1.18));
console.log(withTax);   // → [12, 24, 35]

filter — keep matching items

const scores = [42, 88, 95, 61];
console.log(scores.filter((s) => s >= 70));   // → [88, 95]

reduce — collapse into a single value

const total = [10, 20, 30].reduce((sum, n) => sum + n, 0);
console.log(total);   // → 60

The 0 is the initial accumulator — always pass it for sums and counts (it also handles the empty-array case gracefully).

find / findIndex / some / every / includes

const users = [
  { id: 1, name: 'Asha' },
  { id: 2, name: 'Kai' },
];

console.log(users.find((u) => u.id === 2));        // → { id: 2, name: 'Kai' }
console.log(users.findIndex((u) => u.id === 2));   // → 1
console.log(users.some((u) => u.name.startsWith('A')));  // → true
console.log(users.every((u) => u.id > 0));         // → true
console.log(['a', 'b'].includes('b'));              // → true
MethodReturns
find(fn)First matching element or undefined
findIndex(fn)Index of first match, or -1
indexOf(v)Index of exact value, or -1
some(fn)At least one match? (boolean)
every(fn)All match? (boolean)

Chaining transformations

const orders = [
  { id: 1, total: 120, status: 'paid' },
  { id: 2, total: 45,  status: 'cancelled' },
  { id: 3, total: 300, status: 'paid' },
];

const revenue = orders
  .filter((o) => o.status === 'paid')
  .map((o) => o.total)
  .reduce((sum, t) => sum + t, 0);

console.log(revenue);   // → 420

Expected output: a readable left-to-right pipeline: filter → extract → sum. Each method returns a new array (except reduce), so nothing upstream is mutated.

Arrays of arrays and flat

console.log([1, [2, [3]]].flat(2));        // → [1, 2, 3]
console.log([1, 2].flatMap((n) => [n, n])); // → [1, 1, 2, 2]

Common mistakes

  • Default sort on numbers — lexicographic order; pass a comparator.
  • Mutating shared arrays — push/sort/splice alter the original for every consumer; copy first when in doubt.
  • Using map for side effects — it allocates a new array for its return values; use forEach when you only act.
  • Forgetting return in map's block body — produces an array of undefined.
  • Comparing arrays with === — two arrays are never equal by reference; compare lengths + elements or use JSON.stringify for simple cases.
  • Assuming filter/map are slow — readability wins; profile only when proven hot.

Practice checklist

  1. Given [3, 1, 4, 1, 5], return a sorted copy without touching the original.
  2. Chain filter + map to get names of active users.
  3. Reimplement reduce-based group-counting: count words in an array of strings.
  4. Sort an array of objects by a numeric field (products.sort((a, b) => a.price - b.price)).

Arrays hold values — objects hold named data. Next: Objects & JSON.

Quiz: Arrays & Array Methods

5 questions · 70% to pass

Frequently Asked Questions

JavaScript is the programming language of the web. It adds behaviour to pages: responding to clicks and input, validating forms, fetching data from APIs, updating the DOM without reloading, and much more. It also runs on servers (Node.js), in desktop and mobile apps, and in build tooling.

They are unrelated languages that share a similar name for historical marketing reasons. Java is a statically-typed compiled language; JavaScript is a dynamically-typed interpreted language designed for the browser. Knowing one does not imply knowledge of the other.

Helpful but not mandatory — HTML gives you the structure JavaScript manipulates and CSS the styling it toggles. If you know basic tags, classes and selectors, you have enough to start; the DOM chapters assume only that much.

Use const by default and let when the value must change. Avoid var entirely in modern code: it is function-scoped instead of block-scoped, hoists differently, and can create accidental globals. This course uses const and let throughout.

The Document Object Model is the browser’s in-memory tree of objects representing your HTML. JavaScript reads and modifies that tree — selecting elements, changing text, adding nodes, attaching event listeners — and the browser re-renders the page to match.

== compares after converting types (so 5 == "5" is true), while === requires the same value AND the same type (5 === "5" is false). Loose equality has famously confusing rules — use === and !== everywhere unless you have a specific reason not to.

JavaScript is single-threaded, so long-running work (timers, fetches, events) is handled by the browser and its callbacks are queued. The event loop moves queued callbacks onto the call stack only when it is empty, with promise callbacks (microtasks) taking priority over timers. It is why asynchronous code never freezes the page.

A Promise is an object representing a future value — pending, fulfilled or rejected — that can be chained and combined (Promise.all). async/await is syntax sugar over promises that lets asynchronous code read top-to-bottom with ordinary try/catch error handling.

Yes. Frameworks are built on exactly these fundamentals — components are functions, state is your variable discipline, effects are events, rendering is DOM work. Developers who learn vanilla first understand what the framework is doing and debug far faster.

Type out the examples instead of copying, build small end-to-end projects (expense tracker, weather app, quiz), handle every UI state (loading, empty, success, error), and revisit fundamentals while reading real code. Consistency beats volume — a little most days outpaces occasional marathons.