JS/TS
  • JavaScript Development
  • JS Principles
    • JS Principles
      • Primitive data types
      • typeof operator
      • Scope
      • Hoisting
      • IIFE
      • Closure
      • Anonymous functions in JS
      • Conditional (ternary) operator
        • Coercion vs Conversion
      • Event-driven programming
      • Factory Function
      • JSON.stringify()
      • Strict mode
      • super() keyword
      • What are memory leaks?
      • Micro-tasks within an event loop (Summary)
      • Macro-tasks within an event loop (Summary)
      • null vs undefined
    • Memory Management
    • Advanced function concepts
      • Impure vs Pure Functions
      • Factory functions
  • JavaScript Objects & Arrays
    • Introducing JavaScript objects
      • Build-in objects
        • isNaN()
      • RegExp
        • RegExp.prototype.test()
      • String
        • String.prototype.split()
        • String.prototype.slice()
      • Objects
        • Object.assign()
        • Object.create()
        • Object.defineProperties()
        • Object.defineProperty()
        • Object.entries()
        • Object.freeze()
        • Object.getOwnPropertyNames()
        • Object.getPrototypeOf()
        • Object.isFrozen()
        • Object.isSealed()
        • Map
      • Standard built-in methods to work with Arrays
        • Array.of()
        • Array.prototype.concat()
        • Array.prototype.every()
        • Array.prototype.filter()
        • Array.prototype.find()
        • Array.prototype.findIndex()
        • Array.prototype.forEach()
        • Array.prototype.join()
        • Array.prototype.map()
        • Array.prototype.pop()
        • Array.prototype.shift()
        • Array.prototype.reverse()
        • Array.prototype.some()
        • Array.prototype.sort()
        • Array.prototype.splice()
        • Array.prototype.unshift()
        • Array.prototype.includes()
        • Array.prototype.flatMap()
      • Prototypal inheritance
        • Inheritance with the prototype chain
        • Inheriting "methods"
  • JavaScript Mid
    • JavaScript & ES
      • Arrow Function
      • Anonymous Function
      • Callbacks
      • Promises
      • var, let, and const
      • Fetch API (function)
      • Fetch API
      • Synchronous vs Asynchronous
      • Encapsulation
      • Destructuring assignment
      • call() - apply() - bind()
      • 'This' keyword
      • Functional Programming
  • Browser
    • Event-driven programming
  • TypeScript
    • The TypeScript Handbook
      • Basic Types
      • Interfaces
      • Functions
      • Literal Types
      • Unions and Intersection Types
      • Classes
      • Enums
      • Generics
      • Implements vs extends
  • Hackerrank Practices
    • Practices and examples
  • JS Math
    • Mathematical
      • JavaScript | Math.E() function
      • Math.abs( ) Method
      • Math.ceil( ) function
      • Math floor()
      • Math.imul( ) Function
      • Math log( ) Method
      • Math max()/min() Method
      • Math pow( ) Method
      • Math.sign( ) Function
      • Math sqrt( ) Method
Powered by GitBook
On this page

Was this helpful?

  1. JavaScript Objects & Arrays
  2. Introducing JavaScript objects
  3. Prototypal inheritance

Inheritance with the prototype chain

PreviousPrototypal inheritanceNextInheriting "methods"

Last updated 4 years ago

Was this helpful?

JavaScript objects are dynamic "bags" of properties (referred to as own properties). JavaScript objects have a link to a prototype object. When trying to access a property of an object, the property will not only be sought on the object but on the prototype of the object, the prototype of the prototype, and so on until either a property with a matching name is found or the end of the prototype chain is reached.

Following the ECMAScript standard, the notation someObject.[[Prototype]] is used to designate the prototype of someObject. Since ECMAScript 2015, the [[Prototype]] is accessed using the accessors and . This is equivalent to the JavaScript property __proto__ which is non-standard but de-facto implemented by many browsers.

It should not be confused with the func.prototype property of functions, which instead specifies the [[Prototype]] to be assigned to all instances of objects created by the given function when used as a constructor. The Object.prototype property represents the prototype object.

// Let's create an object o from function f with its own properties a and b:
let f = function () {
   this.a = 1;
   this.b = 2;
}
let o = new f(); // {a: 1, b: 2}

// add properties in f function's prototype
f.prototype.b = 3;
f.prototype.c = 4;

// do not set the prototype f.prototype = {b:3,c:4}; this will break the prototype chain
// o.[[Prototype]] has properties b and c.
// o.[[Prototype]].[[Prototype]] is Object.prototype.
// Finally, o.[[Prototype]].[[Prototype]].[[Prototype]] is null.
// This is the end of the prototype chain, as null,
// by definition, has no [[Prototype]].
// Thus, the full prototype chain looks like:
// {a: 1, b: 2} ---> {b: 3, c: 4} ---> Object.prototype ---> null

console.log(o.a); // 1
// Is there an 'a' own property on o? Yes, and its value is 1.

console.log(o.b); // 2
// Is there a 'b' own property on o? Yes, and its value is 2.
// The prototype also has a 'b' property, but it's not visited. 
// This is called Property Shadowing

console.log(o.c); // 4
// Is there a 'c' own property on o? No, check its prototype.
// Is there a 'c' own property on o.[[Prototype]]? Yes, its value is 4.

console.log(o.d); // undefined
// Is there a 'd' own property on o? No, check its prototype.
// Is there a 'd' own property on o.[[Prototype]]? No, check its prototype.
// o.[[Prototype]].[[Prototype]] is Object.prototype and there is no 'd' property by default, check its prototype.
// o.[[Prototype]].[[Prototype]].[[Prototype]] is null, stop searching,
// no property found, return undefined.
Object.getPrototypeOf()
Object.setPrototypeOf()
Object