JavaScript Guides

Home

Working with JavaScript Prototypes

The object hierarchy in JavaScript enables any object (which in JavaScript is just about everything) to inherit methods and properties. The parent object from which a child inherits is called the child object's "prototype". Prototypes are a great way to teach JavaScript new tricks, and we are going to take a look at some of the things you can do with them in this tutorial.

Extending Objects with Methods and Properties

Let's start by looking at how we normally add a custom method or property to an object in JavaScript, starting with pre-defined objects. In the following code we create a new object (myImage) based on one of JavaScript's built-in objects (Image) and add a custom property (size) to it:

var myImage = new Image();
myImage.size = '50k';

Similarly we can add custom properties to our own custom objects. Here we first define our custom object (circle) using JavaScript's function keyword, then we create a new object (myCircle) based on it, then we add a custom property (diameter) to it:

// Create a custom object type
function circle() {};

// Create an instance of it
var myCircle = new circle();

// Add a property
myCircle.diameter = 4;

In the case of both myImage and myCircle, the new property exists only for our new instance. If we were to create another Image instance (or circle instance), that new instance would not have the size (or diameter) property. And if you tried to read that property, it would return as "undefined".

Extending Instances of a Custom Object

Suppose we want all instances of a particular object to inherit a method or property — for example if we wanted all images to have the size property. How do we do that? We can do it by adding the method or property to our base object's prototype. It is very easy to do this: all we need to do is insert the prototype keyword before the property:

// Create a custom object and add a custom property to it
function circle() {};
circle.prototype.pi = 3.14;

Now all circle instances will have the property pi, and when a new one is created the initial value of that property will be 3.14. We can quickly check this is true using an alert:

var myCircle = new circle();
alert(myCircle.pi); // Displays 3.14

Extending an object's prototype in this way means that all objects created from the prototype will get the new method or property. (At the very top of the JavaScript object hierarchy is a prototype object simply called Object. Any methods or properties that Object has get inherited by all the objects in your JavaScript code. It is not, however, a good idea to add methods or properties to Object itself; usually you will add such extensions to more specialized objects lower down the object hierarchy.)

Extending Instances of a Built-In Object

You can use the prototype keyword with any custom JavaScript object (as we saw above) and also with built-in JavaScript objects like images, strings, dates, and arrays. For example, we can add a custom maxSize property to all images like this:

Image.prototype.maxSize = "500k";

The prototype object can be used with methods as well as properties. In the following example we extend the built-in Number object by adding a method (toRad) that calculates the value of a number in radians (this is a useful method if you end up working with latitude, longitude and distance calculations). First we check to see if the browser's JavaScript implementation already has this method available in its Number prototype, and if it does not, we add the method to the prototype:

if (typeof(Number.prototype.toRad) === "undefined") {
    Number.prototype.toRad = function() {
        return this * Math.PI / 180;
    }
}

(The keyword this in the code above refers to the object on which we invoked the method. For example, when evaluating this code, the value of this in the toRad method will refer to the value of n, which is 45:

var n = 45;
alert(n.toRad());
// Note that calling 45.toRad() will give a syntax error

By now I am sure you can see that a prototype is like a class object in other languages in that it defines the properties shared by all instances of the class. However, unlike a class, a prototype can be retrieved and changed at runtime. New methods and properties can be added and existing methods and properties can be removed.

Some Basic Utility Functions for JavaScript

If you are used to programming in languages like C/C++, you may find that JavaScript is missing many of the built-in functions you normally use. By extending your JavaScript prototypes it is easy to add the missing functions you need. Here are some quick examples:

Remove leading and trailing spaces from strings

String.prototype.trimSpaces = function () {  
    return this.replace( /^\s*(\S*(\s+\S+)*)\s*$/, "$1");   
};   
var myText = '   Some text.   ';  
alert(myText.trimSpaces()); // Displays 'Some text.'

Pad numbers with zeros

Number.prototype.padWithZeros = function (width) {  
    var text = this.toString();  
    for(; text.length < width; ){  
        text = '0' + text;  
    }  
    return text;  
};    
var myNumber = 9876;  
alert(myNumber.padWithZeros(9)); // Displays 000009876 

Capitalize strings

String.prototype.initialCap = function(){
    if(this.length == 0) return this;
    return this[0].toUpperCase() + this.substr(1);
}
var myText = 'foo';
alert(myText.initialCap() ); // Displays 'Foo'

Convert strings to numbers

String.prototype.toNumber = function(){
    return Number(this);
}
var myString = '42';
alert(myString.toNumber() ); // Displays 42

Prototypes in MoSync Wormhole

To give an example of how prototypes are used in library code, here are some code snippets from the PhoneGap library, which is included in the MoSync Wormhole JavaScript Library (that is our library that makes it possible for your JavaScript apps to talk to services on your mobile device).

// Define the Notification object.
var Notification = function() {
};

// Add the vibrate method to the prototype of the Notification object.
Notification.prototype.vibrate = function(mills)
{
    // Calls into native code to perform the vibrate service.
    PhoneGap.exec(null, null, "Notification", "vibrate", {duration:mills});
};

// Create a new Notification child object and set the
// global variable navigator.notification to refer to it.
if (typeof navigator.notification === "undefined") {
    navigator.notification = new Notification();
}

// How to call the vibrate method in your own MoSync application code:
navigator.notification.vibrate(500);



MoSync SDK 3.3
Copyright © 2013 MoSync AB
www.mosync.com