Saturday, February 11, 2012

Prototypes and 'new' statement in Javascript

The blog is now moved here

The purpose of this article is to be a reminder how prototypes in javascript works. It is not full manual or detailed guide how to deal with that. So let's get started.

Classes in javascript is simply functions. Let's create few
var A = function(){
    this.some = 'A value';
    this.another = 'A value another';
}
Now we have two functions which can be be instantiated with new keyword
var a = new A();

Technically there are two properties [[prototype]] and prototype. First  called __proto__ in Gecko browsers so let's use that name.  So what is happening once you call new ? Javascript creates new object and set __proto__ to prototype. That is pretty much it.
a.__proto__ === A.prototype // true
Now, what is happening when you are trying to access an object property like
a.some
First, it trying to find the property directly in object (and it would find it in this case because of this.some = 'A value'). Then, if the property wasn't founded in object it trying to find it in __proto__ which is object too. This process is recursive. Javascript would go down by __proto__s until it find the property.

Summary: Fields search in javascript works through prototypes.

Here is simple example
var B = function(){
    this.some = 'B value'
};
B.prototype = a;
var b = new B();
cc(a.some, a.another);
cc(b.some, b.another);
["A value", "A value another"]
["B value", "A value another"]


You will notice that I use cc function often. It is util tool I use for quick debugging. Here is the code:
function cc(){
    if (arguments.length > 1){
        console.log(arguments);        
    } else {
        console.log(arguments[0]);
    }
}

Note, b.another doesn't set explicitly which means it was taken from a.  Note, if you will change a.another then b.another would change too because __proto__ is just a reference to a object.
a.another = 'completely new value';
cc(a.some, a.another);
cc(b.some, b.another);
["A value", "completely new value"]
["B value", "completely new value"]
Consider the following statement:
A.__proto__ === Function.prototype; // true
this happens because
var SomeClass = function(){};
it is equivalent to
var SomeClass = Function();
and to
var SomeClass = new Function();
so A.__proto__ is taken from Function.prototype as expected.

Function.prototype contain few built in properties like call and apply additionally to Object's properties because Function is extending from Object (actually everything extending from Object in javascript). Also, A.prototype object has constructor property by default which is pointing to A
A.prototype.constructor === A; // true

No comments:

Post a Comment