Object Oriented Javascript

February 16, 2010

Problog

This post will cover the following topics:

  • Javascript is not a toy!
  • How to define a class
  • How to set Publich methods
  • How to set Private variables
  • How to set static methods

JavaScript for Dummies?

Programming languages are like football teams – it doesn’t matter which you like, you will support it and protect its interest no matter what. Back in the days when i was young, I remember the same old discussion between two development teams where i used to work – C++ vs. Delphi. I guess its an endless discussion where the people and the languages change but the content basically stay the same.
What’s weird is that when i talk to fellow developers about JavaScript i get a weird feeling that everybody looks at it as more of a toy rather than a powerful client side development tool. The major critic that i get is this is a very simple functional language, that cannot match to the object oriented concept that drive most languages. One friend even told me that this is a language for bored teenagers.
I agree – JavaScript is an easy to learn language, but that doesn’t mean that it’s a simple one. I see it as a positive thing that you can quickly achieve your goals without needing to know all the language capabilities, and you can learn very fast how to really use the language capabilities to accomplish things even better or faster.
I decided to show how you can shape JavaScript to be used as an Object Oriented language. I don’t think that you must code JavaScript always in object oriented style, but you should have this ability and choose when you think it’s the best solution to implement.

In this post i will focus on the basics of Object Oriented programming – public, private and static declarations.

Defining a Class

In Javascript everything is an object, even functions. In order to define a new class we should just define a new function like so:


function Player(url){}

No in order to create an instance of this class we can write the following:


var player1 = new Player("http://youtube.com/...");

This line of code will create a new instance of the function object and return the reference to it. Not to confuse, but if the function return a value it won’t be placed in player1. for example, let’s say you have a function like so:


function f1(){ return 100;}
var a = f1();
var b = new f1();

The difference between the two is that a will be assigned with 100 while b will be assigned with the reference to a new f1 function object.

Public Methods

As in any object oriented language, the first thing you would like to do is define some public methods for your class. In Javascritp we will use the prototype keyword to setup new methods for this class. You can do this like so:


function Player(url){
}

Player.prototype.start = function(){
//...do some stuff here...
}
Player.prototype.stop = function(){
//...do some stufff here...
}

For those of you who prefer to create classes encapsulated in one declaration you can also write the same code as so:


function Player(url){
}

Player.prototype = {
    start: function(){
        //...do some stuff here...
    } ,
    stop: function(){
        //...do some stuff here...
    }
};

These two declarations achieve the same result. This is part of the reasons that i love javascript so much – it can be so simple and so complicated at the same time.
Now you can use the class methods as so:


var player1 = new Player("http://youtube.com/...");
player1.start();
player1.stop();

Public Variables

In order to set public variables we will use the this keyword that allow us to preserve state for our object.


function Player(url){
    this.url = url;
}

Now we have a public variable that can be accessed using the class properties as so:


var player1 = new Player("http://youtube.com/...");
player1.url = "http://youtube.com/differenturl";
player1.start();

Usually it is bad practice to allow access to the class inner variables, and such variables needs to be set private.

Private Variables

In order to create private variables we would simple declare them in the constructor as so:


function Player(url){
    var m_url = url;
}

Now the variable m_url is not accessible to anyone. Well that doesn’t make sense, right? We want to allow our public methods to access the data.
We solve this using closure. A closure is a protected variable space, created by using nested functions. In order to better understand it we first need to understand how JavaScript function declaration works. Function declaration in Javascritp is based on two main concepts: lexically scoped and function-level scope. Lexically means that function run in the scope they are defined in and not in the scope they are executed in, as other language usually do. Function-level means, like most languages, that a variable declared in function is not accessible outside that function. Using these concepts we can now declare our private variables that will be accessible to our public methods:


function Player(url){
    var m_url = url;
    this.start = function(){
        //now i can access m_url
    };
    this.stop = function(){
        //now i can access m_url
    }
}

The difference between this code and the previous ones, is that the public methods were declared using the prototype while now they are declared using the this keyword. The main difference is in the way the JavaScript engine execute this code. When declaring functions using the prototype, the Javascript engine creates only one instance of the function in memory and dynamically assigns the this according to the calling object. On the other hand, when declaring a method inside the object constructor, as we did in the last example, the JavaScript engine will create a copy of that function in memory for every instance that you create from the Player class. Usually this shouldn’t be a big factor, but its important to know the difference.

Static Methods & Variables

Using closures and the prototype characteristic i mentioned above you can also create static methods like so:


function Player(url){
    var m_url = url;
    this.start = function(){
        //now i can access m_url
    };
    this.stop = function(){
        //now i can access m_url
    }
    var static_int = 0;
    Player.prototype.getStatic = function(){ return static_int;};
    Player.prototype.setStatic = function(v){ static_int = v; };
}

var p1 = new Player();
var p2 = new Player();
p1.setStatic(100);
alert( p2.getStatic() ); //will print 100.

I hope this example shows the power of JavaScript once you understand how to shape it to whatever you need. I the next post I will show how to implement interfaces and inheritance in Javascript.

Update

I got a comment about the static variable implementation, that there is a bug there. I checked it and there is a bug with the way i set the static variable. in order for it to be static we also need to declare it using the prototype as so:


Player.prototype.tatic_int  = 0 ;
Player.prototype.getStatic = function(){ return static_int;};
Player.prototype.setStatic = function(v){ static_int = v; };
Bookmark and Share
Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • E-mail this story to a friend!
  • FriendFeed
  • LinkedIn
  • StumbleUpon
  • Twitter

tags: ,
posted in Blog by Amir Harel

23 Comments to "Object Oriented Javascript"

  1. Michael Pelz-Sherman wrote:

    Hi – nice article!

    Re: your static methods example: in the OO languages I'm familiar with, static vars & methods are accessed via the class name, rather than off instances of the class.

    Here's a version of your example that works that way:

    Player.static_int = 0;
    Player.getStatic = function(){ return static_int;};
    Player.setStatic = function(v){ static_int = v; };

    Player.setStatic(100);
    alert( Player.getStatic() ); //will print 100.

  2. Amir Harel wrote:

    Thanks for the comment.
    You can write many things in more then one way – this is i think what is good and bad in Javascript (depends on the developer skills)

    I showed my example where everything is encapsulated inside the constructor to give it a more C++ feeling, so C++ developers can relate :)

  3. stonezhong wrote:

    In your static method sample, there is a problem, setStatic and getStatic always access the static_int that is associated to the latest instance. It won't work if I insert another “var p3 = new Player()” after p1.setStatic(100), details below:

    function Player(url){
    var m_url = url;
    this.start = function(){
    //now i can access m_url
    };
    this.stop = function(){
    //now i can access m_url
    }
    var static_int = 0;
    Player.prototype.getStatic = function(){ return static_int;};
    Player.prototype.setStatic = function(v){ static_int = v; };

    this.dump = function() { WScript.Echo(static_int); }
    }

    var p1 = new Player();
    var p2 = new Player();
    p1.setStatic(100);
    var p3 = new Player();
    alert.Echo( p2.getStatic() ); //will print 0 instead of 100 !!

  4. stonezhong wrote:

    Hi there, good article. There is a problem with the “Static Methods & Variables” section, since setStatic and getStatic will always try to manipulate the static_int for the latest instance of class Player, so if

    var p1 = new Player();
    var p2 = new Player();
    p1.setStatic(100);
    var p3 = new Player(); // insert this line, then the next line will print 0 instead of 100
    alert( p2.getStatic() ); //will print 0

  5. gilbeRt_fox wrote:

    I made a little jquery plugin.. a multicolumn tree table using this method!

  6. JavaScriptBank.com wrote:

    very cool examples to learn some basic OOP in JavaScript, thank you very much for sharing.

    Can I share this post on my JavaScript library?

    Awaiting your response. Thank

  7. Amir Harel wrote:

    Nice, share the link to the plugin if you like…

  8. Amir Harel wrote:

    Sure, just put the proper credit :)

  9. Leslie_M wrote:

    Amir,

    This is a great, concise explanation. Can you comment on two other JS OO items? First is how creating a JS class then instantiating it differs from creating an OO-like structure (with methods and instance variables) without defining a class. e.g.

    var Player = {
    m_url : undefined,
    start: function() {},
    stop: function() {},
    init: function(url) {m_url = url}
    };

  10. Leslie_M wrote:

    Can you also show an example of how to implement inheritance in JS?

  11. Leslie_M wrote:

    There is a nice summary of Object Literal Notation here:

    http://www.javascriptkit.com/javatutors/oopjs.s…

  12. Amir Harel wrote:

    Thanks for sharing.

  13. Amir Harel wrote:

    I'm writing a post about inheritance and interfaces. I hope to publish it next week.

  14. Manvendra Singh wrote:

    function superClass(){
    this.superClassX = “superX”;
    }

    SubClass.prototype = new SuperClass;
    SubClass.prototype.constructor = SubClass;

    function SubClass()
    {
    SuperClass.call(this);
    this.subClassX = “SubX”;
    }

    var subObj = new SubClass();

    alert(subObj.superClassX + ', ' +subObj.subClassX );

  15. Leslie_M wrote:

    Found two more related articles:

    This one also covers Javascript OO: http://www.digital-web.com/articles/objectifyin…

    And this one covers other useful info such as accessing function arguments, lambda's, and passing functions into functions as an argument: http://www.hunlock.com/blogs/Functional_Javascript

  16. Javascript Inheritance | Amir Harel wrote:

    [...] Object Oriented Javascript [...]

  17. DARRELL wrote:


    MedicamentSpot.com. Canadian Health&Care.No prescription online pharmacy.Best quality drugs.Special Internet Prices. Low price pills. Order pills online

    Buy:Cialis Super Active+.VPXL.Cialis Soft Tabs.Soma.Viagra Super Force.Zithromax.Propecia.Viagra.Viagra Super Active+.Levitra.Tramadol.Cialis.Viagra Professional.Maxaman.Viagra Soft Tabs.Cialis Professional.Super Active ED Pack….

  18. CALVIN wrote:


    CheapTabletsOnline.com. Canadian Health&Care.No prescription online pharmacy.Special Internet Prices.Best quality drugs. Low price drugs. Buy drugs online

    Buy:100% Pure Okinawan Coral Calcium.Synthroid.Nexium.Zyban.Actos.Valtrex.Zovirax.Human Growth Hormone.Mega Hoodia.Prednisolone.Lumigan.Accutane.Arimidex.Prevacid.Retin-A.Petcam (Metacam) Oral Suspension….

  19. KEITH wrote:


    CheapTabletsOnline.com. Canadian Health&Care.Best quality drugs.Special Internet Prices.No prescription online pharmacy. High quality pills. Order pills online

    Buy:Zetia.Aricept.Wellbutrin SR.Zocor.Buspar.Ventolin.Lipitor.Seroquel.Lasix.Benicar.Female Pink Viagra.Nymphomax.Cozaar.Prozac.Female Cialis.SleepWell.Acomplia.Amoxicillin.Advair.Lipothin….

  20. Rajendra wrote:

    There is a small typo in updated code line #1. It should be 'Player.prototype.static_int = 0 ;'. Great stuff though.

    This is one of my attempt at Classical Object Oriented style JS – http://code.google.com/p/oopsjs/

  21. Rajendra wrote:

    There is a small typo in updated code line #1. It should be 'Player.prototype.static_int = 0 ;'. Great stuff though.

    This is one of my attempt at Classical Object Oriented style JS – http://code.google.com/p/oopsj…/

  22. HOMER wrote:


    CheapTabletsOnline.com. Canadian Health&Care.Special Internet Prices.Best quality drugs.No prescription online pharmacy. No prescription pills. Order pills online

    Buy:Zovirax.Valtrex.Retin-A.Accutane.100% Pure Okinawan Coral Calcium.Actos.Mega Hoodia.Prednisolone.Zyban.Prevacid.Petcam (Metacam) Oral Suspension.Synthroid.Nexium.Human Growth Hormone.Arimidex.Lumigan….

  23. Marcos Chioma wrote:

    whatever feels good to you, my man. but,i want nothing to do with this. not here. Anyway, i subscribed to your rss feed which really should do the trick! Have a good day!

 
Powered by Wordpress and MySQL. Theme by openark.org