JavaScript prototype

1:21 PM Xun 1 Comments

I must confess: for the longest time, I did not know anything about JavaScript prototype, nor did I care. I was just programming my way in blissful ignorance, however the frequent talk of and reference to JavaScript prototype finally got me.

Turned out prototype is so fundamental to JavaScript that not knowing about it makes you de-facto handicapped, at least when you go deeper and deeper in the rabbit hole that is JavaScript.

What is prototype? As the term implies, it is a model or process to be replicated or learn from.
From (Wiki: Prototype)

Everything, every product has a prototype. Every car has a prototype, every car built from the prototype automatically inherits the functions from the prototype; Every JavaScript object has a set of prototypal properties and methods, every instance of the object carries on the prototypal properties and methods by default. An array has prototypal methods such as
concat
,
constructor
,
every
,
filter
,
forEach
; A string has a different set of methods for string manipulation such as
charAt
,
big
,
blink
,
bold
.



How do you inspect the prototype of an object?

For objects, you can use
Object.getPrototypeOf
in most modern browsers (IE 9 and above, Chrome, FF); Or simply
__proto__
in non-IE browsers for both objects and other JavaScript primitive data types.


var a = {};
var pa = Object.getPrototypeOf(a);
console.log(pa); // Object

var b = [];
var pb = Object.getPrototypeOf(b);
console.log(pb); //Array

var c = "I am a string.";
var pc = c.__proto__;
console.log(pc); // String

//custom object
var Person = function (name) {
this.name = name;
this.sayName = function () {
console.log (this.name);
}
}

var peter = new Person("peter");
var pp = Object.getPrototypeOf(peter);
console.log(pp); // Object


Alter the prototypal landscape

JavaScript prototype is a powerful thing because it dedicates the genetic make-up of all of its instances and decendants; it is also amazingly meallable, open to alteration and manipulation.

Take the above
Person
constructor for example. The
Person
's prototype is an Object, therefore any
Person
, in our dummy case
Peter
, is pre-loaded with all the methods defined in an object prototype, including
toString
,
toLocaleString
. Therefore peter not only can call its local method sayName, it can also check out the methods in its prototype chain
toString
,
toLocalString
.


peter.sayName(); // peter
peter.toString(); // Object
peter.toLocalString(); // Object


How does peter knows there is a
toString()
method without defining it? Here comes in the concept: prototype chain. What does that mean? It refers the chain of look-ups, the route of upward searching in JavaScript. When a method or a property is called, JavaScript starts searching locally, if find it, great! Execute and return!; if no, one step further, it goes to the prototype of the current object; if still no? It reaches further. So it goes, until it reaches the root of the chain.

A prototype chain is illustrated from the image.




Briefly,

1. JavaScript starts the search with object "a".

2. If no, JavaScript then visits "A.prototype" (the prototype of object "a") and looks for the property.

3. If still no, JavaScript then check "B.prototype" (the prototype of "A") and finds the property. This process of visiting each object's prototype continues until JavaScript reaches the root prototype. This series of links by prototype is called the "prototype chain".

Image and description from Document Object Model Prototypes, Part 1: Introduction

As for the
toString()
method for
peter
, you can see the path of search here:



(Prototype chain is the base of JavaScript chaining, exemplified by jQuery; Prototypal chain has some performance implications. The deeper the root is, the deeper the search goes, the heavier performance penalty is, but that is a topic merits an article of its own.)

Back to the
Person
constructor, it defines a method
sayName
. And now every instance of Person has its copy of
sayName
method. This in itself is a bit of expensive, especially if you have a very complicated
sayName
method; in contrast, make it part of the prototypes makes it more memory efficient. To do so, we get rid of the
sayName
method in the constructor, and add it to the prototypal arsensal:


var Person = function(name){
this.Name = name;
};

Person.prototype.sayName = function(){
console.log(this.Name);
};

var mary = new Person("mary");
mary.sayName(); // mary

This is prototypal inheritance in its simpliest form. And we just successfully changed the prototype of the object
Person
.

If we can make methods part of the prototype, so we can make properties. This can be quite useful if you want to set up some default properties for the object.


var Person = function(name){
this.Name = name;
};

Person.prototype.sayName = function(){
console.log(this.Name);
};

Person.prototype.canTalk = true;

var mary = new PersonP("mary");
mary.sayName(); // mary
console.log(mary.canTalk); // true


JavaScript built-in objects

All the above deals with a dummy customized object. However, it does not mean you cannot add prototypal methods with JavaScript built-in objects, such as
Date
, such as
String
.
Date
is a usual suspect, because people like to manipulate Dates.

For example,


Date.prototype.isAprilFool = function(){
return (this.getMonth() == 3 && this.getDate() == 1)
}


From Date prototype is april fool

Now you have the IsAprilFool judgement call.


var today = new Date();
today.isAprilFool(); // false


Easy!

JavaScript inheritance

Javascript inheritance has many forms in subtle or unsubtle variations. It is the topic of constant and ongoing debates. Nearly all forms of JavaScript inheritance are careful studies of JavaScript prototypes, be it classical or peudo-classical or prototypal inheritance.

Mr. Crockford started with classical, and had written about it in Classical Inheritance in JavaScript, then he is convinced with the superiority of prototypal inheritance, and wrote it at here:Prototypal Inheritance in JavaScript. A lot of other people also have produced beautiful articles even libraries with their own version of extend or inherit, for example, John Resig's Simple JavaScript Inheritance and Defining classes and inheritance from the Prototype JavaScript framework.

But it is late now, I already used up my lunch time plus some other time that is slotted for my work. So, so long.

Source:

The prototype object of JavaScript
http://msdn.microsoft.com/en-us/scriptjunkie/ff852808
Understanding JavaScript Prototypes.

1 comment:

  1. Thanks for the share. Keep posting such kind of information on your blog. I bookmarked it for continuous visit.
    html5 music player

    ReplyDelete