Javascript: Using Prototype

Prototype article banner

It seems that I have missed a major part of Javascript, and even more importantly, I’ve missed one of the fundamental attributes and styles of Javascript! From what I’m seeing round the Internet, I’m definitely not the only one, in fact it seems as if even some seasoned professionals, who’ve worked with Javascript with years, still don’t use or quite understand the concept of prototyping.

I myself am completely new to the concept. I’ve seen code with prototyping in before, but I’ve not known anything about it, and I’ve found other ways around it. If you’ve come across it before, maybe in an older implementation of Javascript, and need your Prototype education rewiring, you should maybe look at the article by Angus Croll (which I’ve also linked in the Further Reading section at the bottom). Otherwise, I’ll see if I can explain it.

You can go without using prototypes directly for as long as you use Javascript, but chances are that you’ll be using prototypes in everything you do and if you’re using a library like jQuery then there’s no question that you’ll be using prototypes. Many core Javascript objects use prototypes already, if you’ve ever use split() or replace() on a string – you’ll have used a prototype. But prototyping is not essential to programming in Javascript, which is why many go without using or knowing about it, however, it is the key to huge performance gains. Something which is very important if you’re making larger, more interactive pages with a lot of Javascript code.

An Example

Finding an example of this which could affect almost all Javascript developers was actually quite hard, as it doesn’t affect many in a massive way until you get into the aforementioned more interactive, larger pages. But I think I’ve found a scenario, sadly I’ve still had to explain a different style of coding, which really could go in another blog, but it’s nevertheless useful to explain objects and their place in programming.

Using simple functions

Say you wanted a set of functions which would change some text in a paragraph tag (<p>), to keep things simple, I only want to change what the actual text says and the colour of the text. Most people would instantly go for the following approach.

function changeText(pTagName, toWhat) {
document.getElementById(pTagName).innerHTML = toWhat;
  return true;
}

function changeColour(pTag, toWhat) {
  //do functions for colour change
  alert("colour changed to "+toWhat);
  return true;
}

And to the value of two p tags, you’d do the following.

changeText("pTag1","This is the new text.");
changeText("pTag2","This is the new text.");

But what if you had 10 things you wanted to be able to do to the paragraph tag? Or 100, what if you wanted to expand it to changing other elements? Really you’d want to have one function that did it all, right?

Using Objects

You can do this by using Objects. With an object you can write methods, which (in this case) will change anything you want about the paragraph tag. In this example, that’ll look like this.

function TextChanger(pTag) {
  this.textObj = document.getElementById(pTag);

  this.changeColour = function(toWhat) {
    //do functions for colour change
    alert("colour changed to "+toWhat);
    return true;
  };

  this.changeWords = function(toWhat) {
    this.textObj.innerHTML = toWhat;
    return true;
  };
}

We can then create an object which will change just the attributes of one paragraph tag each, making it much quicker and easier to manipulate it later on in your script. Now, we’d change the text like this.

//Assign a TextChanger object to both paragraph tags.
var text1 = new TextChanger("pTag1");
var text2 = new TextChanger("pTag2");
text1.changeWords("This was an object method changing me, the first one!");
text2.changeWords("This was an object method changing me, the second one!");

//Aside: If we wanted to change the colour now, we can do it like this.
text1.changeColour("blue");
text2.changeColour("pink");

You could stop there, that will still be faster than the first approach, and now everything will be contained, so things will still be easier to work with. But you can still get faster performance just from this simple example!

Using Prototypes with your Object

The problem is that every time you create a new TextChanger() object, it has to also create an instance of the changeWords() and the changeColour() method. And that can build up a surprising amount, especially if you’re using objects to do something a lot more complex or resource intensive.

So now we’re finally at the point where Prototypes come in. With a prototype, you can declare a function which will be available to every single instance of that TextChanger() object, or whatever object you want. Just about anything that is a function or a value in Javascript can have a prototype. Integers, Strings (more on this later), pre-existing Javascript objects, your own objects, whatever you want.

In our example here, if you use prototypes, it means that Javascript only needs to create one instance of changeWords() and one instance of changeColour() for any instance of TextChanger, whether you have one instance or a million instances. And as before, that really does start affecting performance once you start doing more complex operations!

To use prototypes in our code, we can do the following.

function TextChanger(pTag) {
  this.textObj = document.getElementById(pTag);
}

TextChanger.prototype.changeColour = function(toWhat) {
  //do functions for colour change
  alert("colour changed to "+toWhat);
  return true;
};
TextChanger.prototype.changeWords = function(toWhat) {
  this.textObj.innerHTML = toWhat;
  return true;
};

It’s pretty similar to what we saw in the above example with just declaring an Object. The only difference is that you declare your Object function and then outside of that function, you can declare your methods with “TextChanger.prototype.changeWords =” and your function.

To use it, it’s the same as using an object method (as shown above).

var text1 = new TextChanger("pTag1");
var text2 = new TextChanger("pTag2");
text1.changeWords("This was an object method changing me, the first one!");
text2.changeWords("This was an object method changing me, the second one!");

And to see the results of going through all that change? I’ve set up a benchmark test on jsPerf (a javascript benchmarking site that I would highly recommend!) and you can find that at http://jsperf.com/change-text-test. It differs slightly to the examples shown here, though only marginally. We’re still doing the same operations to get the same result.

In the case of the simple function test, the element has be retrieved each time and then it’s operated on. In the case of the Objects using nested methods, it’s actually slower, in this test, than the simple function! This is because it’s having to retrieve the element the same number of times as the simple function test and it’s having to create several instances of both methods. If you used this approach and did more using it, you’d find that actually, it would come out on top of the simple function test.

But it’s the Object with prototyped test which really shows the improvement on both these methods, it still has to retrieve the element for each paragraph tag, but only one instance of each method is created, and the actual operation takes less time because the element is already stored as an object property.

A time saver using prototypes

Because everything can have a prototype in Javascript, it means you can add some very interesting functionality into core features of Javascript. For instance, lets make a method to add the html entity for a bullet point to any string, using prototypes.

String.prototype.bullet = function() {
 return "&bull; "+this;
}

"Item 1".bullet(); //Returns "&bull; Item 1" or "• Item 1" in HTML

That’s pretty useful, but there are so many more useful things that can be done with prototypes. Explore what there is out there!

Any notes?

It should be noted that if you’re using a Javascript library (like jQuery), then you may come in to some problems with prototyping. Just Googling “prototype and jQuery” will show just a sample of these problems. So just be cautious if you do decide to use both of these together.

Just a quick aside!

Completely unrelated, I’d just like to once again recommend you try Adobe Photoshop CS6 while it’s still running in public beta, I made the banner for this blog post using just CS6 and it just keeps offering more and more. I really am impressed!

Further Reading

 jsPerf Benchmark test using the examples seen here
 General information about optimising your code from Nettuts
 Understanding Javascript Prototypes from the Javascript, Javascript blog
 Dmitry A. Soshnikov’s article on prototypes

About these ads

One thought on “Javascript: Using Prototype

  1. Pingback: Refactoring Code in to an Object-Oriented Paradigm #3: Moving to Object-Oriented code patterns « andrewBridge

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s