In MDN site, why does it say Object.prototype inherits from Function.prototype

Learn in mdn site, why does it say object.prototype inherits from function.prototype with practical examples, diagrams, and best practices. Covers javascript, oop, inheritance development technique...

Demystifying JavaScript's Prototype Chain: Object.prototype and Function.prototype

Hero image for In MDN site, why does it say Object.prototype inherits from Function.prototype

Explore the intricate relationship between Object.prototype and Function.prototype in JavaScript, clarifying common misconceptions about their inheritance and roles in the prototype chain.

When delving into JavaScript's object-oriented nature, the prototype chain is a fundamental concept. However, certain statements, like the one sometimes found on MDN suggesting Object.prototype inherits from Function.prototype, can be confusing. This article aims to clarify this relationship, explaining how these core prototypes fit into the broader inheritance model and why such statements might arise.

Understanding the Core Prototypes

At the heart of JavaScript's inheritance model are Object.prototype and Function.prototype. Every object in JavaScript ultimately inherits from Object.prototype, which provides fundamental methods like toString(), hasOwnProperty(), and valueOf(). Similarly, every function in JavaScript is an instance of Function, and thus inherits from Function.prototype, which provides methods like call(), apply(), and bind().

classDiagram
    Object <|-- Function
    Object.prototype <|-- Function.prototype
    class Object {
        +toString()
        +hasOwnProperty()
    }
    class Function {
        +call()
        +apply()
        +bind()
    }
    class Object.prototype {
        // ... base methods
    }
    class Function.prototype {
        // ... base methods
    }

Simplified class diagram showing the relationship between Object and Function constructors and their prototypes.

The 'Object.prototype inherits from Function.prototype' Misconception

The statement that Object.prototype inherits from Function.prototype is often a source of confusion because, at first glance, it seems to contradict the idea that Object.prototype is the top of the prototype chain. The confusion typically stems from two key observations:

  1. Object is a function: The Object constructor itself is a function. Like all functions, Object inherits from Function.prototype. This means Object.__proto__ === Function.prototype.
  2. Function.prototype is an object: Function.prototype is an object, and like all objects, it ultimately inherits from Object.prototype. This means Function.prototype.__proto__ === Object.prototype.

These two facts create a cyclical-looking relationship if not understood correctly. It's crucial to distinguish between the constructor (Object, Function) and its prototype object (Object.prototype, Function.prototype).

Tracing the Prototype Chain

Let's trace the prototype chains to clarify. Every object has a prototype, which can be accessed via the __proto__ property (though Object.getPrototypeOf() is the preferred modern way).

  1. Object (the constructor function): Object.__proto__ points to Function.prototype. Function.prototype.__proto__ points to Object.prototype. Object.prototype.__proto__ points to null (the end of the chain).

  2. Function (the constructor function): Function.__proto__ points to Function.prototype (functions inherit from Function.prototype). Function.prototype.__proto__ points to Object.prototype. Object.prototype.__proto__ points to null.

  3. Object.prototype (the object): Object.prototype.__proto__ points to null.

  4. Function.prototype (the object): Function.prototype.__proto__ points to Object.prototype. Object.prototype.__proto__ points to null.

The MDN statement likely refers to the fact that Object (the constructor) inherits from Function.prototype, and Function.prototype (the object) inherits from Object.prototype. It's not Object.prototype itself inheriting from Function.prototype directly in the sense of its __proto__ property.

console.log(Object.__proto__ === Function.prototype); // true
console.log(Function.prototype.__proto__ === Object.prototype); // true
console.log(Object.prototype.__proto__); // null
console.log(Function.__proto__ === Function.prototype); // true
console.log(Object.getPrototypeOf(Object) === Function.prototype); // true
console.log(Object.getPrototypeOf(Function.prototype) === Object.prototype); // true

Demonstrating the prototype relationships in JavaScript

graph TD
    subgraph Prototype Chain of Object Constructor
        Object_Constructor["Object (constructor)"] --> Function_Prototype["Function.prototype"]
        Function_Prototype --> Object_Prototype["Object.prototype"]
        Object_Prototype --> Null_Proto["null"]
    end

    subgraph Prototype Chain of Function.prototype Object
        Function_Prototype_Obj["Function.prototype (object)"] --> Object_Prototype_Obj["Object.prototype"]
        Object_Prototype_Obj --> Null_Proto_Obj["null"]
    end

Visualizing the distinct prototype chains for the Object constructor and the Function.prototype object.