easyJS ES5#62

typeof vs instanceof

Prompt

Write typeChecker(value) returning a string describing the value's type. It must return 'null' for null (not 'object'), 'array' for arrays, 'date' for Date instances, and fall back to typeof for everything else.

Solution

function typeChecker(value) {
  if (value === null) return 'null'
  if (Array.isArray(value)) return 'array'
  if (value instanceof Date) return 'date'
  return typeof value
}
Mentor's take

This challenge exists because JavaScript's two type operators answer different questions and each has a famous blind spot — reliable runtime type checks are built by ordering guards around both. typeof reports the primitive category and is safe on anything (including undeclared names), but it lies twice: typeof null === 'object' — a bug from the first JavaScript implementation, now permanently spec'd because fixing it would break the web — and every object, arrays included, is just 'object'. instanceof walks the prototype chain, so it distinguishes object flavors, but it can't handle primitives and it's identity-based: an object from another realm (an iframe, a worker boundary, some serialization layers) was built by a different Array constructor, so instanceof Array returns false on a perfectly good array.

The guard order in the solution encodes all of that. null first, by strict equality, before anything that would misreport it. Array.isArray next — it checks the internal class rather than the prototype chain, which is exactly why it's cross-realm safe and the canonical array test. instanceof Date for the remaining object flavor we care about. typeof as the fallback where it's trustworthy: primitives, functions, undefined. And note typeChecker(NaN) returns 'number' — correctly, since NaN is a number value per IEEE 754.

Red flag: value instanceof Array. It works until data crosses a realm boundary, and "why is this array not an array" is a genuinely miserable production debug.

Say it: "typeof lies about null and flattens objects; instanceof fails across realms — so I check null by equality, arrays with Array.isArray, and fall back to typeof only for primitives."