Prototype in Javascript at Five Levels

Level 1: Child

Imagine you have a toy robot, and you want all robots made after it to be able to do the same things - walk, talk, etc. In this case, your toy robot is like a ‘prototype’ in JavaScript. It’s the model that all future robots (or in JavaScript, objects) can look at to see what they should be able to do.

Level 2: Teenager

In JavaScript, a prototype is like a cheat sheet for objects. If an object wants to do something and it doesn’t know how, it looks at its prototype to see if there’s a way to do it there. This is how JavaScript shares functions and properties between objects.

Level 3: College Student

JavaScript is a prototype-based language, meaning it doesn’t have classical inheritance like other programming languages. Each object in JavaScript has a link to another object: its prototype. If you try to access a property or method that an object doesn’t have, JavaScript will look for it in the object’s prototype. This is called prototype chain or prototype inheritance.

Level 4: Grad Student

In JavaScript, when you create a constructor function to instantiate objects, the prototype is an object shared among all instances created with that constructor. It’s used to implement inheritance and shared behavior. Any modification to the prototype affects all object instances, even those created before the modification. This has performance benefits, as methods are not redefined for each new object, but also requires care to avoid unintentional mutation of shared behavior.

Level 5: Colleague

JavaScript’s prototypal inheritance is one of its most powerful and yet misunderstood features. Understanding prototypes is fundamental for mastering the language, especially when dealing with constructor functions, classes, and higher-order functions. Prototypes can be manipulated to extend built-in JavaScript objects, a feature which, if used judiciously, can be very powerful, or can be used to create mixins for composing behavior in objects. It’s crucial to understand the prototype chain for debugging and for understanding property lookup and function delegation.

Prototype Based Inheritance in Self

Self is an object-oriented programming language based on the concept of prototypes, which is a departure from the class-based inheritance model used in many other languages.

In Self, objects are created by cloning existing ones (known as prototypes) and then modifying the cloned object. There’s no distinction between classes and instances; any object can be cloned to create a new object. Instead of creating classes to generate instances, you simply clone an existing object and make the required modifications.

For instance, consider an object named point, which represents a point in a 2-dimensional space:

point = ( | x = 0. y = 0. | )

Here, point is an object with two slots, x and y.

To create a new point, we clone point and modify the slots x and y:

newPoint = point clone.
newPoint x: 10.
newPoint y: 20.

Now newPoint is an object that represents a point at (10, 20).

We can also add new slots to newPoint:

newPoint = ( | parent* = point. z = 0. | )
newPoint z: 30.

Now newPoint is a point in 3-dimensional space at (10, 20, 30).

In Self, the asterisk (*) after parent denotes a parent slot. When a message is sent to an object, Self first looks for the corresponding method in the object itself. If it doesn’t find it, it looks in the parent objects.

Prototype-based programming such as this allows for a more flexible and intuitive model of object-oriented programming than class-based inheritance. Objects can be modified and extended on the fly, leading to simpler and more dynamic code.

JavaScript Example

JavaScript uses a form of prototype-based inheritance that’s somewhat similar to Self. Every JavaScript object has an internal property, its “prototype”, which is just another object. When trying to access a property that the object doesn’t have, JavaScript will look at its prototype instead.

For instance, let’s start with a point object:

1
let point = { x: 0, y: 0 };

Here, point is an object with two properties, x and y.

To create a new point, we can create a new object and assign point as its prototype:

1
2
3
let newPoint = Object.create(point);
newPoint.x = 10;
newPoint.y = 20;

Now newPoint is an object that represents a point at (10, 20).

We can also add new properties to newPoint:

1
newPoint.z = 30;

Now newPoint is a point in 3-dimensional space at (10, 20, 30).

In JavaScript, the Object.create() function creates a new object with the specified prototype object and properties. When you try to access a property that doesn’t exist on newPoint, JavaScript will look up the prototype chain to point to see if the property exists there. This is the core of prototype-based inheritance in JavaScript.