How to create objects in object-oriented javascript

Javascript is a functional programming language thus having no “real” objects. You can write it the way you want : procedural spag, functional, object or whatever word you know. Why should I write it object-oriented? Because, OO has proven many times its ease of use and great encapsulation. In this paper, I won’t talk about why but about how.

There are hundreds of way of writing OO javascript, I tried a lot of the most commons and I finally adopted one : oo using prototypes.

1. Creating an empty class

I like cats so here’s a complete example for a cat that meows.

First, I create an empty class.

[source:javascript]
function Cat() {
}
[/source]

Hmmmm… that looks a lot like a function. In fact, it’s a function. Why classes are function? Because javascript is a functional language. More on that later (maybe).

2. Creating the constructor

When I have a cat that meows, I want to see its name. I add a name property that is initialized in the constructor of the class.

[source:javascript]
function Cat(name) {
this.name = name;
}
[/source]

What is this? This, is a reference on the current instance of the object. By calling this.name = name, we instantiate an public variable for the object that has the value name (the name of the cat).

3. Adding a instance method

As I said earlier, I want the cat to meow. So, I will add a meow() method to the class that will be available to every instance.

[source:javascript]
function Cat(name) {
this.name = name;
}

Cat.prototype.meow = function() {
alert(”meow!”);
}
[/source]

I used the class’ prototype. This is one of the hundred ways of adding a method but it’s the best way because we create a single reference for all the objects of that class.

4. Using variables of an object

Hey, didn’t you read the specs? I said that I wanted to see the name of the meowing cat.

[source:javascript]
Cat.prototype.meow = function() {
alert(this.name + ” : meow!”);
}
[/source]

Did you see? I used the this (reference on the current instance of the object). By doing that, I simply call the variable that I defined in my constructor (see point #2).

5. Making the cat meow

Now I’m ready to make the cat meow. On the onload property of the body element, I call a function named bodyOnload.

<html>
<body onload=’bodyOnLoad();’ />
</html>

In the bodyOnLoad function, I create a Cat object and call the meow() method.

[source:javascript]
function bodyOnLoad() {
var mistigri = new Cat(’Mistigri’);
mistigri.meow();
}
[/source]

I should see an message box with the message “Mistigri : meow!” inside.

In conclusion

Ok, that was an easy one but though it may seem obvious to you, it is not alway as clear for some of my fellows. The important thing I wanted to show was how to create a class method (see point #3). This is the best/safest/fastest way of doing this.

Commentaires

  1. William Murray March 23 2007 at 12:33:50

    I prefer to assign the methods within the main function, like this:

    function Cat(name) {
    this.name = name;

    this.meow = function() {
    alert(this.name + ” said meow!”);
    }
    }

    To me, this is cleaner than having a list of separate functions. All of the classes methods are contained in the class function. I first saw this when using Actionscript to create runtime functions, and I started using it in Javascript, where it works great. Any advantages or disadvantages to using this over prototype?

  2. Ganeshji Marwaha March 23 2007 at 16:03:38

    concise and clean. but the only problem that i can see in this method is that there is no enclosed view of a class as it is in other OO languages. This has been solved in javascript, but still, i agree that this is the quickest and the easiest way to create a class in javascript.

  3. Dan (maintainer of Javascript Kata) March 23 2007 at 17:40:27

    Thanks for the comment. But I’m not really sure of what you mean? Can you tell me more (or in another way?)

  4. Dan (maintainer of Javascript Kata) March 25 2007 at 16:06:33

    William, pardon me for my late response but Akismet marked your comment as spam. I will have to be more careful and have an eye over it…

    The disadvantage of doing it that way is that it uses more memory. You can see in another of my post about advatages of using prototypes : “It uses less memory because javascript creates only one instance of the function and uses references to it.” (http://www.javascriptkata.com/2007/03/21/what-are-javascript-prototypes-short-answer-for-advanced-javascripters/).

    Thanks for the comment!

  5. Ganeshji Marwaha March 27 2007 at 14:34:40

    Dan - What i meant was, in other OO languages, take java for example, you have an enclosed view of a class and its methods.

    Class Test {
    public void tryMe() {
    System.out.println(”tried”);
    }
    }

    Where as, using the prototype technique, you don’t get such an enclosed view. I don’t tend to see this as a disadvantage, rather as something that will be visually more appealing.

  6. David Mercer March 30 2007 at 16:33:50

    William Murray wrote:

    “I prefer to assign the methods within the main function…Any advantages or disadvantages to using this over prototype?”

    I used to prefer your method, too, but performance is significantly worse with your approach because every time you instantiate an object, a new function is created.

    Mind you, most people treat Javascript as kind of a toy language and don’t expect much performance from it, but detach the interpreter from the browser and you can write quite powerful programs with decent performance.

    My preferred approach is more along the lines of:

    function Cat.prototype.meow(){…}

    rather than

    Cat.prototype.meow = function(){…}

    These work slightly different as functions (and, in this case, methods) declared like mine exist when the first line of the program executes. Using the “Cat.prototype.meow = function” approach, the method will only exist after the program has executed that line of code. Thus, my program could begin with the lines:

    var mistigri = new Cat(’Mistigri’);
    mistigri.meow();

    Whereas the “Cat.prototype.meow = function” approach would choke on that, since the meow method does not exist yet.

  7. Jim Plush April 11 2007 at 10:31:43

    I’d have to agree with the author, using prototype over inner functions reduces the memory footprint. I have to work on 233mhz boxes and trust me, every little bit helps.

    If you want to see pretty classes you could always do this:

    function myClass() {}

    myClass.prototype = {

    test:function() {

    alert(’hi’);
    },

    test2:function() {
    // something here
    }
    };

  8. David Mercer April 11 2007 at 10:46:43

    I wrote:

    > My preferred approach is more along the lines of:

    > function Cat.prototype.meow(){…}

    As has been pointed out to me, Firefox chokes on this syntax. I’ve been using WSH to run Javascript, so never tried it in a browser. It does work in IE, but not Firefox, so my approach is probably out for usage where you do not control script host.

    Jim Plush wrote:

    “If you want to see pretty classes you could always do this:…”

    I like Jim’s approach.

  9. Dan (maintainer of Javascript Kata) April 11 2007 at 15:43:06

    Yeah! Jim’s approach looks good but it can be hard to understand for beginners. I’ll try to write about it in a near future…

  10. […] Kata has a teriffic an article on how to create objects with JavaScript the old fashion way, without any JavaScript libraries. But I use prototype and it has its very own […]

  11. Andrew Sazonov May 1 2007 at 11:35:25

    Yes, approach described in the post works. But unfortunately, it is far from being perfect…

    Here is a link to an article which compares various techniques to implement inheritance in JavaScript (and their benefits and drawbacks):

    http://www.soft-amis.org/jsiner/inheritance.html

Post a comment

Comments are moderated and innapropriate ones won't be approved. Please respect this public space.