JavaScript Inheritance
As a prototype-based language, JavaScript has a less apparent way of defining object hierarchies. But of course it’s doable.
Prototype
-
What is a prototype?
A prototype is an object which other objects reference by their
[[Prototype]]
property.The
[[Prototype]]
property is typically implemented by__proto__
:var a = {}; a.__proto__;
-
Which objects have a prototype?
By default, all objects (except one) have a prototype. Explained next.
-
What is a prototype chain?
Assume by default. Since every object (except one) has a prototype, an object’s prototype also has a prototype, an object’s prototype’s prototype also has a prototype, etc.:
a.__proto__; a.__proto__.__proto__; a.__proto__.__proto__.__proto__; ...
This forms a prototype chain.
-
What’s the only one object that doesn’t have a prototype?
It’s the default object sitting at the end of all prototype chains:
a.__proto__.....__proto__.__proto__; > null
-
Why is prototype chain useful?
An object inherits properties from objects on its prototype chain, in order:
var a = { 'name': 'myname' }; var b = new Object(); b.__proto__ = a; var c = new Object(); c.__proto__ = b; c.name; > 'myname' b.name = 'mynewname'; c.name; > 'mynewname'
The counterpart of prototype in a class-based language is class.
-
Is there a standard accessor to access an object’s prototype?
ECMAScript 5 introduces
Object.getPrototypeOf()
to get an object’s prototype:var a = {}; var b = Object.getPrototypeOf(a); b === a.__proto__; > true
However, it’s only a getter and you cannot use it to set an object’s prototype.
-
How can I create an object with a specified prototype?
Say we want to create an object
b
which has prototypea
.-
Since ECMAScript 5:
var b = Object.create(a);
-
Before ECMAScript 5:
function F() {}; F.prototype = a; var b = new F();
-
Function
-
Does every function has a prototype?
Yes. Every object (except one) has a prototype and a function is an object (and is not the exception).
-
A function has a
prototype
field. What’s that?It’s the prototype of all objects created by this function when it’s used as a constructor:
F = function() {}; f = new F(); f.__proto__ === F.prototype; > true
Don’t mess it up with the prototype of the function itself:
f.__proto__ == F.__proto__ > false
The
prototype
field only exists in function objects. -
What’s does a freshly created
prototype
look like?An object with a
constructor
field, which is the function that created this object.F.prototype.constructor === F; > true
Inheritance
-
How to implement inheritance in JavaScript?
Say we want to let
Extend
extendBase
:Base = function () { ... // init Base members } Extend = function() { Base.call(this); // init Base members ... // init Extend members } Extend.prototype = Object.create(Base.prototype); // set Extend objects' prototype Extend.prototype.constructor = Extend; // amend Extend object's prototype