9

We can use Object.prototype.toString.call(foo) to detect object class (the type of foo), and it works well.

But why does Object.toString.call({}) throw TypeError: Function.prototype.toString is not generic?

Doesn't Object.toString inherit from Object.prototype?

GregL
  • 37,147
  • 8
  • 62
  • 67

1 Answers1

12

Doesn't Object.toString inherit from Object.prototype

No. The built–in Object constructor is a Function (like all native constructors), so it inherits from Function.prototype (i.e. its private [[Prototype]] property references Function.prototype) before its own prototype property.

Its prototype chain is:

Object[[Prototype]] -> Function.prototype -> Object.prototype -> null

so Function.prototype.toString masks Object.prototype.toString.

A bit of trivia: note that while Function.prototype is a function, it doesn't inherit from itself but from Object.prototype.

RobG
  • 142,382
  • 31
  • 172
  • 209
  • 1
    Just to make this clearer: `Object.__proto__ === Function.prototype`. – c10b10 Feb 02 '16 at 16:36
  • @RobG. > "while Function.prototype is a function" but IMHO, `constructor.prototype` are always `objects`. `Function.prototype.prototype` gives `undefined` which is correct, since pure objects (i.e. not function objects) do not have a `prototype` property only function objects do however when I echo `Function.prototype` inside chrome's console it does echo `function () {}`. Can you plz throw some light as to why this gogglee-boggleness? – dkjain Oct 09 '16 at 13:36
  • @dkjain—it's explained in [*ECMA-262*](http://ecma-international.org/ecma-262/7.0/index.html#sec-properties-of-the-function-prototype-object): "*The Function prototype object … is itself a built-in function object. … It does not have a [[Construct]] internal method so it is not a constructor.*" so does not have a default *prototype* property. It's a special case in that it's a built–in function that isn't a constructor. That is also possible for host functions, there is no requirement that they must be constructors (e.g. *Document.getElementById* is not a constructor in browsers I've tested). – RobG Oct 09 '16 at 23:03