prototype, __proto__ and classes with JS

Those aforementioned three words are relative to JavaScript and could sound very weird. Let’s try to understand them!


JavaScript’s object system is based on prototypes, not classes. But what is the difference?

A class is like a blueprint. It is a description of the object to be created. Classes inherit from classes and create subclass relationships.

A prototype is a working object instance. Objects inherit directly from other objects.

Every JavaScript object has a prototype. The prototype is also an object. All JavaScript objects inherit their properties and methods from their prototype. Objects created using an object literal, or with new Object(), inherit from a prototype called Object.prototype. The Object.prototype is on the top of the prototype chain.

function talk() {
console.log(this.sound);
}
let animal() {
talk;
}
let cat() {
sound: "Dog"
}
let cat() {
sound: "Maouw"
}
Object.setPrototypeOf(dog, animal);
Object.setPrototypeOf(cat, animal);
dog.talk; //will output "Woof"
cat.talk; //will output "Maouw"

If we want to add a property or a method to the prototype, we can do it like so:

Animal.prototype.name = "My pet"; 
Animal.prototype.beNice = function() {
console.log("I am nice");
};

We can also use the new operator which will call a constructor function. A constructor could be any function. Basically, when a constructor function is called, the following things happen:

  • A new object is created
  • The constructor property of the object is set
  • The object is set to delegate to the prototype
  • The prototype is called in the context of the new object

So, with a constructor function, we can use the new keyword to create new objects from the same prototype:

function Animal(sound) {
this.sound = sound;
  this.makeSound = function() {
console.log(this.sound);
}
}
var dog = new Animal("Woof");
var cat = new Animal("Maouw");
dog.makeSound(); //will output "Woof"
cat.makeSound(); //will output "Maouw"

Adding a new property to an existing object can be done like that:

dog.color = "Brown";

The property will be added to dog, not to cat and not to any other Animal objects.

Adding a new method to an existing object can be done this way:

cat.playWithMouse = function () {
return "I am playing with a mouse!";
};

The method will only be added to cat.

Now, maybe you saw something like proto and asked what it is.

proto is the actual object that is used in the lookup chain to resolve methods. It is a property that all objects have. This is the property which is used by the JavaScript engine for inheritance. According to ECMA specifications it is supposed to be an internal property, however most vendors allow it to be accessed and modified. The use of proto is controversial, and has been discouraged. It was never originally included in the ECMA specifications, but modern browsers decided to implement it anyway.

prototype is a property belonging only to functions. It is used to build proto when the function happens to be used as a constructor with the new keyword.

So, where are the classes? In essence, a JavaScript class is just a Function object that serves as a constructor plus an attached prototype object Empty also referred as this. Classes in ES6 don’t add any functionality to what we already have in the language, they are just a simpler syntax for building the same objects as we had before. The class syntax is not introducing a new object-oriented inheritance model to JavaScript. JavaScript classes provide a much simpler and clearer syntax to create objects and deal with inheritance.

class Animal {
constructor(sound) {
this.sound = sound;
}
    talk() {
console.log(this.sound);
}
}