algoro.dev

Mastering Arrays in JavaScript: From Basics to Interview-Ready Exercises

10/5/2025 • 10 min read
#Javascript #Data Structures #Arrays #Coding Interviews #Beginners

If you’ve ever stored a list of items—like favorite movies, user emails, or even a to-do list—you’ve already used an array. It’s one of the simplest yet most powerful data structures. Arrays organize elements sequentially in memory, making it super fast to access any element using its index.

In JavaScript, arrays are dynamic, meaning you can keep adding or removing elements without worrying about memory management. But don’t be fooled by their simplicity—understanding arrays deeply gives you a massive edge in interviews and in real-world coding.


How Arrays Actually Work

Behind the scenes, arrays are stored in contiguous memory blocks. That’s why computers can find any element instantly using its index. This lookup operation runs in O(1)—constant time.

But not all operations are created equal.

Adding or removing from the end of an array (push and pop) is lightning-fast. However, inserting or deleting from the start (unshift or splice) is slower—O(n)—because every other item has to move one step.

Here’s a quick summary:

OperationTime ComplexityDescription
Access (get)O(1)Direct index lookup
Push / PopO(1)Add or remove from end
Unshift / SpliceO(n)Insert/delete in middle or start

That trade-off explains why other data structures (like linked lists) exist—they’re optimized for cases where insertions and deletions matter more than random access.


Static vs. Dynamic Arrays—The Memory Game

In low-level languages like C or C++, arrays are static. You have to declare their size upfront (int numbers[10]). Need to add an 11th element? Tough luck—you’ll have to create a new array and copy everything over.

JavaScript, Python, and Java use dynamic arrays. They grow automatically when full: the engine allocates a bigger chunk of memory (often twice the size), copies existing data, and adds your new element. Most of the time, push() runs in O(1), but during that occasional resize, it jumps to O(n).

So next time you push() without thinking, remember—your array might be silently doing a lot of work for you.


Building Your Own Array (Yes, Really)

To truly grasp arrays, nothing beats building one from scratch. Let’s create our own version—MyArray—using a JavaScript class.

class MyArray {
  constructor() {
    this.length = 0;
    this.data = {};
  }
  get(index) {
    return this.data[index];
  }
  push(item) {
    this.data[this.length] = item;
    this.length++;
    return this.length;
  }
  pop() {
    const lastItem = this.data[this.length - 1];
    delete this.data[this.length - 1];
    this.length--;
    return lastItem;
  }
  delete(index) {
    const item = this.data[index];
    this.shiftItems(index);
    return item;
  }
  shiftItems(index) {
    for (let i = index; i < this.length - 1; i++) {
      this.data[i] = this.data[i + 1];
    }
    delete this.data[this.length - 1];
    this.length--;
  }
}

This mini array supports get, push, pop, and delete. It mirrors how JavaScript arrays actually behave under the hood—constant-time access and amortized constant-time inserts at the end, but slower deletions in the middle.

If you understand this, you already understand dynamic arrays at their core.


Classes, References, and Context in JavaScript

While we’re at it, let’s clear up a few concepts that often confuse developers when working with objects and arrays.

Arrays are reference types, meaning that if you assign one array to another variable, they both point to the same place in memory. Mutate one, and you mutate both.

const a = [1, 2];
const b = a;
b.push(3);
console.log(a); // [1, 2, 3]

Also, understanding this inside classes helps prevent weird bugs. In JavaScript, this refers to who called the function, not necessarily where it’s defined. Arrow functions, however, inherit this from their surrounding scope—a subtle but crucial distinction when designing reusable data structures or classes.


Exercise 1: Reverse a String

A classic warm-up problem that’s deceptively simple.

Prompt:

Reverse a string like this: “Hi My Name is Alex” → “xelA si emaN yM iH”

Approach 1 — Manual Loop

function reverse(str) {
  if (!str || typeof str !== 'string' || str.length < 2) return str;
  const backwards = [];
  for (let i = str.length - 1; i >= 0; i--) {
    backwards.push(str[i]);
  }
  return backwards.join('');
}

Approach 2 — Built-in Methods

function reverse(str) {
  return str.split('').reverse().join('');
}

Approach 3 — ES6 One-liner

const reverse = str => [...str].reverse().join('');

All three have the same O(n) time complexity—but showcasing multiple solutions in interviews shows flexibility and depth.


Exercise 2: Merge Two Sorted Arrays

Another staple interview problem: merging two sorted arrays into one sorted array.

Example: [0,3,4,31] and [4,6,30] → [0,3,4,4,6,30,31]

Solution:

function mergeSortedArrays(arr1, arr2) {
  if (arr1.length === 0) return arr2;
  if (arr2.length === 0) return arr1;

  const merged = [];
  let i = 0, j = 0;

  while (i < arr1.length && j < arr2.length) {
    if (arr1[i] < arr2[j]) {
      merged.push(arr1[i]);
      i++;
    } else {
      merged.push(arr2[j]);
      j++;
    }
  }
  return merged.concat(arr1.slice(i)).concat(arr2.slice(j));
}

This algorithm runs in O(n + m) time and is an excellent example of pointer logic, a foundational technique for many more advanced problems (like merging linked lists or sorted intervals).


Wrapping Up—Why Arrays Still Matter

Arrays might feel basic, but mastering them means mastering memory, complexity, and logic. They’re a microcosm of how computers think—linear, efficient, and structured.

Every time you push(), splice(), or even write a for loop, you’re working with the same principles that power modern algorithms. And as you move on to more complex data structures—linked lists, stacks, trees—you’ll keep finding that arrays are the foundation of it all.


Final Thought:

If you can implement, explain, and optimize arrays confidently, you’ve already crossed the first big hurdle of algorithmic thinking. Everything else builds from here.