July 2014
A prototype in JavaScript is an object with a special role: it's the parent of another object. And the role of a parent is to provide properties to its children.
Let's see how a prototype is linked to another object.
[[Prototype]]
Every object has an internal property named [[Prototype]]
. The value
of [[Prototype]]
is either a reference to another object or
null
. Example:
Observations:
a
has no prototype.a
is the prototype of b
.a
and b
form a prototype chain starting at b
.a[[Prototype]]; // => null
b[[Prototype]]; // => a
Note that this is not valid JavaScript code as we cannot access
directly an internal property of an object. We will see later how to
retrieve the value of [[Prototype]]
.
Let's now see what's the purpose of the prototype chain.
When a reference is made to a property in an object, the interpreter
first looks if a property of that name is contained in the object. In
that case, its value is returned. Otherwise, the interpreter checks
its object's prototype (referenced by the [[Prototype]]
internal
property), then the object's prototype's prototype and so on. This
process continues until the property is found or the interpreter
reaches the end of the prototype chain. In that case, undefined
is
returned.
Example:
a.p1; // => 'a-1'
a.p2; // => 'a-2'
a.p3; // => undefined
a.p4; // => undefined
b.p1; // => 'b-1'
b.p2; // => 'a-2'
b.p3; // => 'b-3'
b.p4; // => undefined
[[Prototype]]
Every function comes with a prototype
property (not to be confused
with the [[Prototype]]
internal property) whose value is an empty
object.
When a function is used as a constructor (i.e. called as part of a
new
expression) the value of the [[Prototype]]
internal property
of the newly created object is set to the value of the prototype
property of the function. Example:
var A = function () {};
A.prototype; // => {}
var a1 = new A(); // A is invoked as a constructor.
a1[[Prototype]]; // => A.prototype
var a2 = new A();
a2[[Prototype]]; // => A.prototype
Let's add properties to those objects:
var A = function () {};
A.p1 = "A-1";
A.p4 = "A-4";
A.prototype.p1 = "A-P-1";
A.prototype.p3 = "A-P-3";
var a1 = new A();
a1.p1 = "a1-1";
var a2 = new A();
a2.p2 = "a2-2";
And let's see how they are looked up:
A.p1; // => 'A-1'
A.p2; // => undefined
A.p3; // => undefined
A.p4; // => 'A-4'
A.prototype.p1; // => 'A-P-1'
A.prototype.p2; // => undefined
A.prototype.p3; // => 'A-P-3'
A.prototype.p4; // => undefined
a1.p1; // => 'a1-1'
a1.p2; // => undefined
a1.p3; // => 'A-P-3'
a1.p4; // => undefined
a2.p1; // => 'A-P-1'
a2.p2; // => 'a2-2'
a2.p3; // => 'A-P-3'
a2.p4; // => undefined
A
is not part of the prototype chains starting at a1
and
a2
. Thus, it has no influence when a property is looked up in a1
and a2
.
To keep things simple, some objects were omitted in the previous examples. Let's add the native objects (bold) to the previous example.
The properties of the native objects are documented in the ECMAScript Language Specification. Below are links to an annotated version of the specification for the corresponding objects:
By following the dashed lines, we know exactly what properties are
inherited by each object. For instance, properties defined in
Object.prototype
(such as toString
and hasOwnProperty
) are
inherited by all objects, because every prototype chain ends with
Object.prototype
.
[[Prototype]]
There is currently one standard way to access the [[Prototype]]
internal property of an object and it's by using the function
Object.getPrototypeOf
. Example:
var A = function () {};
var a = new A();
Object.getPrototypeOf(a) === A.prototype; // => true
Although most implementations currently support the __proto__
property, it is not part of the current standard (ECMAScript 5). But
it will most likely be part of the next
standard. Example:
a.**proto** === A.prototype // => true
[[Prototype]]
internal property.[[Prototype]]
internal property is
called a prototype chain.prototype
property.[[Prototype]]
internal
property of the newly created object is set to the prototype
property of the
function.Need a search bar for your website? Make it easy for visitors to find what they need with Lixia Search.