Peter Chang

@peterchang_82818

Javascript inheritance behind the scene __proto__, [[prototype]] and prototype

The prototype is a property on a constructor function that sets what will become the __proto__ property on the constructed object.

The key to understanding inheritance in Javascript is to understanding how a Javascript Egg laying process by the parent hen; Javascript inheritance happens in prototype inherited but classical class technically and conceptually is not existed.

This is a note about clearing up the confusion of prototype, __proto__ and inheritance in Javascript. Most of the content here is collected from the two very great articles by Dmitry Soshnikov and Kenneth Kin Lum : http://dmitrysoshnikov.com/ecmascript/javascript-the-core/
https://kenneth-kin-lum.blogspot.tw/2012/10/javascripts-pseudo-classical.html?showComment=1484288337339#c1393503225616140233

Example 0 : [[prototype]] vs __proto__ vs prototype

speakingjs.com and javascripttutorial.com are the best resource which explains the relation of [[prototype]], __proto__ and prototype from the basic to application, also very important that they visualize the relation in graphic.

Every object can have another object as its prototype. Then the former object inherits all of its prototype’s properties. An object specifies its prototype via the internal property [[Prototype]]. The chain of objects connected by the [[Prototype]] property is called the prototype chain:
http://speakingjs.com/es5/ch17.html
To see how prototype-based (or prototypal) inheritance works, let’s look at an example (with invented syntax for specifying the [[Prototype]] property):
var proto = {
describe: function () {
return 'name: '+this.name;
}
};
var obj = {
[[Prototype]]: proto,
name: 'obj'
};
> obj.describe
[Function]
> obj.describe()
'name: obj'
The __proto__ is an accessor property of the Object.prototype object. It exposes the internal prototype linkage ( [[Prototype]]) of an object through which it is accessed (by javascripttutorial).
function Foo(name) {
this.name = name;
}
var b = new Foo('b');
var a = new Foo('a');
b.say = function() {
console.log('Hi from ' + this.whoAmI());
}
console.log(a.__proto__ === Foo.prototype); // true
console.log(a.__proto__ === b.__proto__); // true
http://www.javascripttutorial.net/javascript-prototype/
JavaScript engine adds the say() method to the b object, not the Foo.prototype object.
As you see in the diagram, the a.__proto__ exposes the [[Prototype]] that points to the Foo.prototype object. Similarly, b.__proto__ also points to the same object as a.__proto__:

Example 1 : creating object by constructor

This is a example from Dmitry, about creating objects by constructor, it is going to show how an prototype and __proto__ works in inheritance mechanism.

Besides creation of objects by specified pattern, a constructor function does another useful thing — it automatically sets a prototype object for newly created objects. This prototype object is stored in the ConstructorFunction.prototype property.
E.g., we may rewrite previous example with b object using a constructor function. Thus, the role of the object a (a prototype) Foo.prototype plays:

Create Foo object with prototype x and calculate()

function Foo(y) {
this.y = y;
}
Foo.prototype.x = 10;
Foo.prototype.calculate = function
(z) {
return
this.x + this.y + z;
};

Create instance b using the object Foo:

var b = new Foo(20);
b.calculate(30); // 60
console.log(
b.__proto__ === Foo.prototype, // true
b.__proto__.calculate === Foo.prototype.calculate // true
b.__proto__.calculate === b.calculate, // true
Foo === b.constructor, // true
Foo === Foo.prototype.constructor, // true
);
As it is showed above, b is inherited the methods from Foo(). “Foo.prototype” automatically creates a special property “constructor”, which is a reference to the constructor function itself.
Instances “b” may found it via delegation and use to check their constructor.
from: http://dmitrysoshnikov.com/ecmascript/javascript-the-core/

Example 2 : JavaScript Classical Inheritance diagram

This is an example from Kenneth, also about creating object by constructor but we are focus on the issue of prototype chain during those series of objects and instances. Prototype objects are also just simple objects and may have their own prototypes. If a prototype has a non-null reference to its prototype, and so on, this is called the prototype chain (by Dmitry).

The following is a chart of JavaScript Pseudo Classical Inheritance. The constructor Foo is just a class name for an imaginary class. The foo object is an instance of Foo.

https://kenneth-kin-lum.blogspot.tw/2012/10/javascripts-pseudo-classical.html?showComment=1484288337339#c1393503225616140233

And now we can see from the diagram why when we inherit Dog from Animal, we would do:

function Dog() {} // the usual constructor function
Dog.prototype = new Animal();
Dog.prototype.constructor = Dog;

What happens when new( ) an instance:

Note that the prototype in Foo.prototype is not to form a prototype chain. Foo.prototype points to some where in a prototype chain, but this prototype property of Foo is not to form the prototype chain. What constitute a prototype chain are the __proto__ pointing up the chain, and the objects pointed to by __proto__, such as going from foo.__proto__, going up to foo.__proto__.__proto__, and so forth, until null is reached.

Relation of __proto__ and prototype

JavaScript’s Pseudo Classical Inheritance works like this way: I am a constructor, and I am just a function, and I hold a prototype reference, and whenever foo = new Foo() is called, I will let foo.__proto__ point to my prototype object. So Foo.prototype and obj.__proto__ are two different concepts. Foo.prototype indicates that, when an object of Foois created, this is the point where the prototype chain of the new object should point to — that is, foo.__proto__ should point to where Foo.prototype is pointing at.

What if a function is needed to add

If woofie the object doesn’t have the move method, it will go up the prototype chain, just like any prototypal inheritance scenario, first to the object pointed to by woofie.__proto__, which is the same as the object that Dog.prototype refers to. If the method move is not a property of that object (meaning that the Dog class doesn’t have a method move), go up one level in the prototype chain, which is woofie.__proto__.__proto__, or the same as Animal.prototype.
Animal.prototype.move = function() { ... };
https://kenneth-kin-lum.blogspot.tw/2012/10/javascripts-pseudo-classical.html?showComment=1484288337339#c1393503225616140233
Even though foo.constructor === Foo, the constructor property is not foo’s own property. It is actually obtained by going up the prototype chain, to where foo.__proto__ is pointing at. The same is for Function.constructor. The diagram can be complicated, and sometimes confusing when we see Constructor.prototype, foo.__proto__, Foo.prototype.constructor.
To verify the diagram, note that even though foo.constructor will show a value, the property constructor is not foo’s own property, but is obtained by following up the prototype chain, as foo.hasOwnProperty(“constructor”) can tell.

Notes:

[[Prototype]]An object specifies its prototype via the internal property

__proto__ brings direct access to [[Prototype]] to the language(by speakingjs.com).

prototype is the object that is used to build __proto__ when you create an object with new.

prototype is not available on the instances themselves (or other objects), but only on the constructor functions.

prototype is only available on functions since they are copied from Function and Object, but in anything else it is not. However, __proto__ is available everywhere.

( new Foo ).__proto__ === Foo.prototype  //true
( new Foo ).prototype === undefined //true

delegate prototypes and concatenative inheritance

Cat.prototype = new Animal();
//it will properly follow the prototype chain through the inheritance hierarchy.
Cat.prototype = Animal.prototype
//
any runtime changes to the Cat prototype would also affect the Animal

static properties/functions do not exist on the prototype. The prototype is only used when a newinstance is created.

Like this story? It is helpful to others? It helps me know if you’d like to see write more about his topic and helps people see the story, when tap the heart below.

More by Peter Chang

Topics of interest

More Related Stories