Friday, July 17, 2015

Javascript Prototypes and Prototype Pattern

JAVASCRIPT PROTOTYPES

Reason why i am blogging about this because i seriously like to share how i got my confusion removed regarding JavaScript Prototypes, i used prototypes for last 3 years just because someone has used it and with a confusion regarding its basics i was just implementing it, this is the case with many of us and this is one of the most confusing topic until unless you don't explore it practically.

I will show you how i actually got clear about prototype and finally i love these and consider its pattern as the most handy and important when comes to developing APPS.

Note:- I am using Chrome Developer tools console tab for demonstrations.

Prototype, as per the oxford dictionary a prototype is  :-

A first, typical or preliminary model of something, especially a machine, from which other forms are developed or copied.

So in simple words prototype is a model to create copies out of, and if i relate it at this point with JavaScript and my programming knowledge so it must be my functional blueprints to create objects out of, which is partially true but it has more functionality, now lets see what popular article says about prototype as single lines definitions:-
  1. A prototype is an object from which other objects inherit properties.
  2. Every JavaScript object has a prototype. The prototype is also an object.
  3. All JavaScript objects inherit their properties and methods from their prototype.
So keeping above three definitions in mind i thought to explore it Chrome browser console and see the practicality of definitions. But first for folks  who does not know what a JavaScript object is!
 here is a quick information:-

JavaScript Object (Layman Language {key:value} )
A JavaScript object is really just an unordered collection of key:value pairs, and you create  key:value pairs separated by commas and packed in Mustaches(Curly Braces):-

var Student = {Name:'John Doe', ID:1} // this is a container with properties.


A JavaScript object contains properties as shown above and can also contain methods/functions too :-

var Student = {Name:'John Doe', ID:1,SayHi:function(){alert('hey By ' + this.Name)}}

And to access property one has to use:- Student.Name or Student['Name']

To access methods:-
Student.SayHi();

Analyze JavaScript Object in Chrome console window for prototype

Open Chrome, default will be google.com, and just press F12 open console (Open Console window, i have put it in the source tab)
  1. There are many ways to create a simple blank object:-

  2. As you can see above i created ankur1,ankur2 and ankur object by different ways.
  3. Now when i checked my object ankur i can see some method which says ankur.isPrototypeOf () which raised my eye brows and immediately i thought using this method i can actually verify and relate the second definition which says every Object has a prototype.
Now if every object has prototype which is an object then there ankur.prototype should be that property/object.
Thinking the same when i checked in my browser console i got surprised to see that ankur.prototype is undefined:-

so is the definition wrong or confusing? Actually it turned out that it was  confusing not wrong:-

The true prototype of an object is held by the internal [[Prototype]] property. ECMA 5 introduces the standard accessor Object.getPrototypeOf(object) which to-date is implemented in Firefox, Safari, Chrome and IE9. In addition all browsers except IE support the non-standard accessor __proto__


And every object is created using with a Constructor initiation so we can access prototype object using prototype property of constructor too(this works in every browser):-


Now this gave me a bigger clarification on the definition of prototype:-

Every JavaScript object has a prototype. The prototype is also an object.

 Lets move forward and analyze the use of prototypes with its two other significant definition:-

  • A prototype is an object from which other objects inherit properties.
  • All JavaScript objects inherit their properties and methods from their prototype.


To show exactly what these two definition mean, we need first to know something very unique to functions in javscript:-

Every function in javscript has a property called prototype, and we use functions to create objects like i did above when used function Object() with new to create ankur1, just see this :-


Now as shown in the console above, we created a new function Myfunction and it does have a prototype Object which is the same when we create a new object as "new Myfunction()" and try to get the Prototype of that Object.

This prototype property does have significance when  functions are used as constructors to construct a Javascript Object.
A function’s prototype property is the object that will be assigned as the prototype to all instances created when this function is used as a constructor.

There is chain in javascript Objects, every Objects inherits from Object.prototype which sits at the top of the Chain.

Moving forward, i saw many examples on net where people have defined one level of inheritance using Protoypes, you can find multiple blogs which talks about single level of inheritance like this example:-



var humanConstructor = function human(name) { this.Name = name };
var Male = new humanConstructor("Man");
var Female = new humanConstructor("woman");
//later on i added this..
humanConstructor.prototype.From = function () {
    this.Name === "Man" ? alert("I am from Mars") : alert("I am from Venus");
}

Male.From();//Output:"I am from Mars"
Female.From();//Output: "I am from Venus"

The above example is very nice and simple one level inheritance example of prototypes definition mentioned above.
I just added From later on and automatically it got inherited by my objects.

Using this way i can customize my initial functions(constructors) and add Methods to prototype Object later on, Automatically all my Objects constructed using initial function will get new methods.
But it stores the reference of prototype not the value.


Till this it was fine, but later i thought:-
How can i create a Object from Male(from above example)  example Boy, and test multilevel inheritance and Chain behavior. And if i try to do this :-


var Boy = new Male(); //This will give error.

I got error:-

So, after a research i learned about Object.create()

So What does actually Object.create() do?

  • Object.create(proto [, propertiesObject ])

It extends a prototype and also can add properties using propertiesObject parameter.

So this is the way to create multilevel inheritance and define the chain mechanism in prototype.

See the use of Object.create():- here:-




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

var Male = new humanConstructor("Man");
var Female = new humanConstructor("woman");

//later on i added this..
humanConstructor.prototype.From = function () {
    this.Name === "Man" ? alert("I am from Mars") : alert("I am from Venus");
}

Male.From();
Female.From();
Male.About = "I am the man";
//Object.getPrototypeOf(Boy).About = "My Name is George, and i am  a Male";
var Boy = Object.create(Male);
alert(Boy.About);//I am the Man
alert(Female.About);//Unidentified
alert(Boy.Name);//Man
alert(Female.Name);//woman


One practical use of prototypes:-
This was where i recently used prototypes, i created a single page app that is meant to work on every browser, it was required to work even in IE8, there is a function in latest browsers called  "toISOString()", this was not working in IE8 and some other versions of browsers, but i did used it excessively, so to overcome the issue i used prototypes and created this :-



 if (!Date.prototype.toISOString) {
        (function () {
            function pad(number) {
                var r = String(number);
                //it takes data type in consideration...
                if (r.length === 1) {

                    r = '0' + r;
                }
                return r;

            }

            //here in this case of prototype pattern, this is the object/datatype on which prototype is applied.
            Date.prototype.toISOString = function () {

                return this.getUTCFullYear()
                   + '-' + pad(this.getUTCMonth() + 1)
                   + '-' + pad(this.getUTCDate())
                   + 'T' + pad(this.getUTCHours())
                   + ':' + pad(this.getUTCMinutes())
                   + ':' + pad(this.getUTCSeconds())
                   + '.' + String((this.getUTCMilliseconds() / 1000).toFixed(3)).slice(2, 5)
                   + 'Z';
            };
        }());
    }

Still there is enough left to discuss about JavaScript Prototype but in this blog i wanted to discuss the actual basics of prototypes with practical impressions. Hope it helps.

No comments:

Post a Comment