Hiprup

How do you implement Array.map from scratch?

map creates a new array by running a callback on every element.

The approach:

  1. Create an empty result array.

  2. Loop over the original array by index.

  3. Call the callback with (element, index, array) and push its return value.

  4. Return the new array, leaving the original unchanged.

Key points: don't mutate the input, and pass index and array as the second and third callback arguments.

// Implementation
Array.prototype.myMap = function(callback, thisArg) {
  if (typeof callback !== 'function') {
    throw new TypeError(callback + ' is not a function');
  }

  const result = new Array(this.length);
  for (let i = 0; i < this.length; i++) {
    if (i in this) { // Handle sparse arrays
      result[i] = callback.call(thisArg, this[i], i, this);
    }
  }
  return result;
};

// Test
const numbers = [1, 2, 3, 4, 5];
console.log(numbers.myMap(n => n * 2));        // [2, 4, 6, 8, 10]
console.log(numbers.myMap((n, i) => n + i));    // [1, 3, 5, 7, 9]

// Standalone version (not modifying prototype)
function map(arr, callback) {
  const result = [];
  for (let i = 0; i < arr.length; i++) {
    result.push(callback(arr[i], i, arr));
  }
  return result;
}

console.log(map([1, 2, 3], x => x * 10)); // [10, 20, 30]

myMap creates a new array of the same length. For each element, it calls the callback with (element, index, originalArray) and stores the result. callback.call(thisArg, ...) sets the this context.

The i in this check handles sparse arrays (arrays with holes). A new array is returned — the original is never modified.

Know the callback signature: (element, index, array). Always create a new array (never mutate).

The sparse array check (i in this) is a detail that shows thoroughness. callback.call(thisArg, ...) for this binding. The standalone version avoids prototype modification (safer for interviews).

How do you implement Array.map from scratch? | Hiprup