liveBook · Manning

Prototype

As explained in Secrets of the JavaScript Ninja, Second Edition

An object from which another object can inherit properties in JavaScript.

Need several objects to share a method? Assigning it to each object is tedious and easy to get wrong. A prototype gives those objects somewhere else to look: if a property is missing from an object, JavaScript searches its prototype. This is the basis of prototype-based inheritance. section 7.1 section 7.2

Property lookup can continue through a prototype chain: the prototype may have a prototype of its own. The search stops when there are no more prototypes to check. `Object.setPrototypeOf(object, prototype)` establishes a link; the object's internal `[[prototype]]` is not the same thing as a constructor function's public `.prototype` property. section 7.1 section 7.2

Listing 7.1. With prototypes, objects can access properties of other objects
const yoshi = { skulk: true };                              #A
const hattori = { sneak: true };                            #A
const kuma = { creep: true };                               #A

assert("skulk" in yoshi, "Yoshi can skulk");                #B
assert(!("sneak" in yoshi)), "Yoshi cannot sneak");         #B
assert(!("creep" in yoshi)), "Yoshi cannot creep");         #B

Object.setPrototypeOf(yoshi, hattori);                      #C

assert("sneak" in yoshi, "Yoshi can now sneak");            #D
assert(!("creep" in hattori)), "Hattori cannot creep");     #E

Object.setPrototypeOf(hattori, kuma);                       #F
assert("creep" in hattori, "Hattori can now creep");        #G
assert("creep" in yoshi, "Yoshi can also creep");           #H

Follow the property checks as two prototype links are added: a property missing from the first object becomes accessible through the chain. section 7.1

A method shared through construction

`function Ninja() {}` `Ninja.prototype.swingSword = function () { return true; };` `const ninja = new Ninja();` `ninja.swingSword(); // true` Calling `Ninja()` normally returns `undefined` here. Calling `new Ninja()` creates an object whose prototype is the function's `.prototype` object, so the new object can use `swingSword`. section 7.2

Watch the timing. Add a method to a prototype object after constructing an instance, and that instance can use it. Replace the constructor's `.prototype` with a different object, however, and existing instances retain their old prototype; only later instances use the replacement. Changing a shared object and replacing it are different moves. section 7.2.2

Keep these distinctions handy:

  • An object's own property is checked before lookup is delegated along its prototype chain. section 7.1
  • A constructor's `.prototype` supplies the prototype for objects it creates with `new`; it is not itself the internal `[[prototype]]` link. section 7.1 section 7.2
  • ES6 `class` and `extends` provide class-like syntax, but prototypes remain behind the scenes. section 7.5

How Secrets of the JavaScript Ninja, Second Edition covers it

How deep it goes
Works through prototype-chain lookup, constructor-created links, and runtime changes; does not describe engine-level lookup internals.
Examples
Uses linked objects with property checks, a constructor-provided method, and prototypes changed after instantiation.
What it assumes
Assumes familiarity with JavaScript objects and functions; explains delegated property lookup and constructor–prototype links directly.
What you can do after
Build it from scratch by linking objects or assigning shared methods to a constructor's prototype, and predict which instances see later changes.
How it connects
Connects property lookup with inheritance, constructor functions, and ES6 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 Secrets of the JavaScript Ninja, Second Edition. The section links point to the parts of the book it draws on.