liveBook · Manning

Prototype

As explained in Essential TypeScript 5, Third Edition

The prototype system is JavaScript's object-inheritance mechanism in which objects delegate property and method lookup to prototype objects.

A JavaScript object has a link to another object called its prototype. When a property or method is not found on the object, JavaScript follows that link, continuing along the prototype chain until it finds the member or reaches the end. This lets objects share behavior without each defining its own copy. An object literal can call an inherited method such as toString() even when the literal does not define it. section 4.2

Inspecting a shared prototype

In index.js, two object literals can be checked with `Object.getPrototypeOf(hat) === Object.getPrototypeOf(boots)`. The comparison is true. Changing `toString` through that shared prototype changes the method both objects use—not just the method used by `hat`. section 4.2.1

Be careful when changing a prototype shared by unrelated objects. A replacement toString() that expects name and price properties will not suit every object. For objects known to have those properties, define a dedicated prototype and assign it with Object.setPrototypeOf(). That prototype can itself have a prototype, so lookup still follows a chain. section 4.2.2

Listing 4.6 Using a custom prototype in the index.js file in the primer folder
let ProductProto = {
    toString: function() {
        return `toString: Name: ${this.name}, Price: ${this.price}`;
    }
}

let hat = {
    name: "Hat",    
    price: 100,
    getPriceIncTax() {
        return Number(this.price) * 1.2;
    }    
};

let boots = {
    name: "Boots",    
    price: 100,
    getPriceIncTax() {
        return Number(this.price) * 1.2;
    }        
}

Object.setPrototypeOf(hat, ProductProto);
Object.setPrototypeOf(boots, ProductProto);

console.log(hat.toString());
console.log(boots.toString());

The index.js listing assigns one custom prototype to two product objects, giving each the same toString() implementation without changing the prototype used by other object literals. section 4.2.2

A constructor function combines object creation, property setup, and prototype assignment through `new`. The function sets each new object’s properties through `this`; methods intended for all its objects go on the function’s `prototype` property. For example, `Product.prototype.toString = function() { ... }` supplies the method used by objects created with `new Product(...)`. section 4.2.3

To build an inheritance chain with constructor functions:

  • Call the base constructor with the new object as `this`, as in `Product.call(this, name, price)`, so its properties are initialized. section 4.2.4
  • Link the prototype objects—not the constructor functions—with `Object.setPrototypeOf(TaxedProduct.prototype, Product.prototype)`. A method on the first prototype can then find a method on the second. section 4.2.4
  • A nearer method with the same name shadows one farther along the chain. To build on the shadowed method, call it through the prototype that defines it, such as `Product.prototype.toString.call(this)`. section 4.2.4

Use `instanceof` with a constructor to check whether its prototype occurs in an object’s chain. For a direct prototype check without a constructor, use `isPrototypeOf` on the prototype object. section 4.2.5

JavaScript class syntax uses this same prototype system. Class methods are added to the prototype assigned to instances; `extends` and `super` provide class syntax for inheritance and calling superclass behavior. Understanding prototypes therefore helps explain what a class instance inherits and why an overridden method runs. section 4.2.7

How Essential TypeScript 5, Third Edition covers it

How deep it goes
Works through lookup, shared-prototype changes, custom chains, constructors, shadowing, and type checks using code examples.
Examples
Uses hat and boots objects, product constructors, taxed products, and index.js listings to trace shared methods and inheritance.
What it assumes
Assumes familiarity with JavaScript object literals and methods while explaining prototype inspection and constructor-based inheritance.
What you can do after
Build it from scratch with custom or constructor prototypes, and diagnose inherited-method lookup with prototype checks.
How it connects
Connects prototypes to object inheritance, constructor functions, method overriding, instanceof, and JavaScript classes.

Also explained in

Compare how 3 books explain prototype →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Essential TypeScript 5, Third Edition. The section links point to the parts of the book it draws on.