Q18: Implement a polyfill for the instanceof operator.

Difficulty:IntermediateTopic:Prototypes

Answer

The instanceof operator normally checks whether a constructor's prototype appears anywhere in an object's prototype chain.

function myInstanceOf(object, constructor) {
  if (
    (typeof object !== "object" || object === null) &&
    typeof object !== "function"
  ) {
    return false;
  }

  if (typeof constructor !== "function") {
    throw new TypeError("Right-hand side must be callable");
  }

  if (!constructor.prototype || typeof constructor.prototype !== "object") {
    throw new TypeError("Constructor prototype must be an object");
  }

  let current = Object.getPrototypeOf(object);

  while (current !== null) {
    if (current === constructor.prototype) {
      return true;
    }

    current = Object.getPrototypeOf(current);
  }

  return false;
}

function Animal(name) {
  this.name = name;
}

const dog = new Animal("Buddy");

console.log(myInstanceOf(dog, Animal)); // true
console.log(myInstanceOf(dog, Object)); // true
console.log(myInstanceOf({}, Animal)); // false

Explanation

The algorithm starts at the object's immediate prototype and traverses the chain until it finds the constructor's prototype or reaches null.

Important limitation

Native instanceof supports custom behavior through Symbol.hasInstance and has specific semantics for unusual constructors. This implementation covers the conventional prototype-chain case.

Key Takeaways
  • Instanceof normally checks the prototype chain, not an object's constructor property.
  • Custom Symbol.hasInstance behavior is outside this simplified implementation.