Gyaan

Polyfills

advanced polyfill interview array-methods bind implementation

A polyfill is a piece of code that implements a feature on browsers or environments that don’t natively support it. Interviewers love asking us to write polyfills because it tests whether we truly understand how these methods work under the hood — not just how to use them.

Array.prototype.myMap

map creates a new array by calling a callback on every element. The callback receives (element, index, array).

Array.prototype.myMap = function(callback, thisArg) {
  const result = [];
  for (let i = 0; i < this.length; i++) {
    if (i in this) { // skip holes in sparse arrays
      result.push(callback.call(thisArg, this[i], i, this));
    }
  }
  return result;
};

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

Array.prototype.myFilter

filter creates a new array with only the elements where the callback returns true.

Array.prototype.myFilter = function(callback, thisArg) {
  const result = [];
  for (let i = 0; i < this.length; i++) {
    if (i in this && callback.call(thisArg, this[i], i, this)) {
      result.push(this[i]);
    }
  }
  return result;
};

// Usage
const nums = [1, 2, 3, 4, 5];
console.log(nums.myFilter(n => n % 2 === 0)); // [2, 4]

Array.prototype.myReduce

reduce is the trickiest one. It takes a callback and an optional initial value. If no initial value is provided, the first element is used as the accumulator and iteration starts from index 1.

Array.prototype.myReduce = function(callback, initialValue) {
  let accumulator;
  let startIndex = 0;

  if (initialValue !== undefined) {
    accumulator = initialValue;
  } else {
    if (this.length === 0) throw new TypeError('Reduce of empty array with no initial value');
    accumulator = this[0];
    startIndex = 1;
  }

  for (let i = startIndex; i < this.length; i++) {
    if (i in this) {
      accumulator = callback(accumulator, this[i], i, this);
    }
  }
  return accumulator;
};

// Usage
const nums = [1, 2, 3, 4];
console.log(nums.myReduce((sum, n) => sum + n, 0)); // 10
console.log(nums.myReduce((sum, n) => sum + n));     // 10 (no initial value)

Function.prototype.myBind

bind creates a new function with this locked to a specific value. It can also pre-fill arguments (partial application). This one is probably the most asked polyfill in interviews.

Function.prototype.myBind = function(thisArg, ...boundArgs) {
  const fn = this;
  return function(...callArgs) {
    return fn.apply(thisArg, [...boundArgs, ...callArgs]);
  };
};

// Usage
const user = { name: 'Manish' };

function greet(greeting, punctuation) {
  return `${greeting}, ${this.name}${punctuation}`;
}

const greetManish = greet.myBind(user, 'Hello');
console.log(greetManish('!'));  // 'Hello, Manish!'
console.log(greetManish('.')); // 'Hello, Manish.'

The key things to remember about bind: it returns a new function (doesn’t call it immediately), it permanently sets this, and any arguments passed to bind are prepended to the arguments passed when the bound function is called.

In simple language, writing polyfills shows the interviewer that we understand what’s happening inside these methods — the loop, the callback signature, the this context, and edge cases like sparse arrays or missing initial values.