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
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
> obj.describe[Function]
> obj.describe()'name: obj'
The
__proto__
is an accessor property of theObject.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 theb
object, not theFoo.prototype
object.
As you see in the diagram, the
a.__proto__
exposes the[[Prototype]]
that points to theFoo.prototype
object. Similarly,b.__proto__
also points to the same object asa.__proto__:
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.prototype.x = 10;Foo.prototype.calculate = function
Create instance b using the object Foo:
var
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/
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.
And now we can see from the diagram why when we inherit Dog from Animal, we would do:
function Dog() {} // the usual constructor functionDog.prototype = new Animal();Dog.prototype.constructor = Dog;
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.
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.
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() { ... };
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.
**[[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();
Cat.prototype = Animal.prototype//
static properties/functions do not exist on the prototype. The prototype
is only used when a new
instance 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.
http://speakingjs.com/es5/index.html
http://www.javascripttutorial.net/javascript-prototype/
http://stackoverflow.com/questions/9959727/proto-vs-prototype-in-javascript
http://dmitrysoshnikov.com/ecmascript/javascript-the-core/
https://www.quora.com/What-is-the-difference-between-__proto__-and-prototype
http://www.jisaacks.com/prototype-vs-proto/
http://kenneth-kin-lum.blogspot.tw/2012/10/javascripts-pseudo-classical.html