Q2: Implement a polyfill for Array.prototype.map().

Difficulty:BeginnerTopic:Array Methods

Answer

The map() method creates a new array by applying a callback to each existing element of the original array. It does not mutate the original array.

A good polyfill should support the callback arguments value, index, and array, an optional thisArg, and sparse arrays.

Array.prototype.myMap = function (callback, thisArg) {
  if (this == null) {
    throw new TypeError("Array.prototype.myMap called on null or undefined");
  }

  if (typeof callback !== "function") {
    throw new TypeError("Callback must be a function");
  }

  const array = Object(this);
  const length = array.length >>> 0;
  const result = new Array(length);

  for (let i = 0; i < length; i++) {
    if (i in array) {
      result[i] = callback.call(thisArg, array[i], i, array);
    }
  }

  return result;
};

console.log([1, 2, 3].myMap(n => n * 2));
// [2, 4, 6]

How it works

  1. Validate the receiver and callback.
  2. Convert the receiver to an object and capture its length.
  3. Create a result array with the same length.
  4. Visit only indexes that exist in the source array.
  5. Store the callback result at the corresponding index.
  6. Return the new array.

The i in array check preserves holes in sparse arrays. The unsigned right shift used above is a common interview simplification for obtaining a 32-bit unsigned length; it is not fully specification-compliant for every possible array-like object. A production-quality implementation should use LengthOfArrayLike semantics.

Map polyfill usage
const numbers = [1, 2, 3, 4];

const doubled = numbers.myMap((value, index, array) => {
  console.log(index, array === numbers);
  return value * 2;
});

console.log(doubled); // [2, 4, 6, 8]
console.log(numbers); // [1, 2, 3, 4]
💡 The callback receives the current value, index, and original array. The returned array contains transformed values without modifying the original array.
Key Takeaways
  • Map returns a new array and preserves the source array.
  • A robust implementation handles sparse arrays, callback validation, and thisArg.