Javascript object prototype
The javascript object prototype is javascript’s way of sharing implementation across similar objects, much like the way classes are used to do this in many other languages. Although constructor functions look a lot like classes, javascript does not have a class based object system like C# or Java. Instead it has a prototype based object system.
The main difference between the two types of languages is all about objects and classes. In a class based language there is a clear distinction between the ideas of a class and an object. A class is a template for creating an object and an object is a specific instance of a class. In C# you cannot create an object without instantiating it from a class. Even the most basic object of type Object is instantiated from a class. Once the object is created you cannot make it into a different type of object by adding different properties.
In a prototype based systems there are no classes. All objects are created by adding properties and methods to an empty object or by cloning an existing one. Although a constructor function may look like a class (probably so people from more traditional class based languages would be able to use it), it’s really just a function that knows how to add the right properties and methods to create a particular type of object.
This approach is called prototype-based inheritance because an existing object is used as a template (or a prototype – a typical example) to build other objects. The existing object will be used as a starting point to build the new object but the new object does not have to be exactly the same.
How it works in javascript
Prototypes are implemented in javascript using the prototype property of constructor functions. Any property or method that’s added to the constructor’s prototype automatically becomes part of every object created by that function.
The prototype property is basically a template for the objects created by the constructor. It contains the things that should be the same among all objects created by the constructor. Individual objects can override and change the things they inherit from the constructor’s prototype but they will all start out the same.
The aim of the prototype is to share implementation between similar objects, to make things more convenient for programmers. It is not designed to be a type system. Javascript objects are dynamic so they can be changed after they are created. Knowing that an object was created by a particular constructor function does not guarantee anything about the methods or properties that an object will have.
A simple example
The easiest way to understand this is to look at an example, so let’s take a look at the Pet example again.
All the pets created by the pet constructor function have a sayHello() method. When we created our pet using the constructor function, we created a separate sayHello() function for each pet by creating the function and adding it to the new object we were creating:
-
function Pet(name, species, hello)
-
{
-
this.name = name;
-
this.species = species;
-
this.hello = hello;
-
this.sayHello = function()
-
{
-
alert(this.hello);
-
}
-
}
Wouldn’t it be better if there would be just one sayHello() function that all the pet objects will automatically share? To do this we could remove the sayHello() method from the constructor function and add it to the function’s prototype property instead:
-
function Pet(name, species, hello)
-
{
-
this.name = name;
-
this.species = species;
-
this.hello = hello;
-
}
-
-
Pet.prototype.sayHello = function()
-
{
-
alert(this.hello);
-
}
-
-
var rufus = new Pet("Rufus", "cat", "miaow");
-
rufus.sayHello();
When we created the Pet function, its prototype property was automatically set to an empty object. Every function is set up this way when it’s created because there’s no way for javascript to know whether any particular function will be used as a constructor function or not.
We wanted all our pets to have a sayHello method, so we added a sayHello() method to the Pet’s prototype property. The prototype property contains a regular javascript object so this is just the same as assigning a new method or property to any other object. In this case we have created a new anonymous function and assigned it to a property called sayHello.
When we created the rufus object, it automatically maintained an invisible link back to the Pet function that created it. Then when we tried to access the sayHello() method, javascript first looked for a sayHello() method set directly on the rufus object. When it couldn’t find one, it then looked at the Pet constructor’s prototype, found sayHello() and called that instead.
Because the property resolution happens when the property is called, any changes made to the prototype property will be reflected in all of the objects already created by the constructor. Properties can be dynamically added or removed or the prototype could even be replaced with an entirely new object.
This all happens transparently. The code that is using the rufus object doesn’t need to care whether rufus’ sayHello() method was set directly on rufus or if it belongs to the Pet constructor.
The prototype property is just an object
The prototype property is just an object. There’s nothing particularly special or magic about it. Anything you can do to a normal object you can also do to a function’s prototype property. This includes adding and removing properties, accessing the properties through substring (Pet.prototype["property"]) or dot (Pet.prototype.property) notation and iterating through the properties using a for loop.
When a new function is created the prototype property is set to an empty object, exactly the same if we said Pet.prototype = new Object() when we created the function. Javascript does this by default whenever you create a new function to make sure that any objects created by calling the function will automatically get all of the methods and properties that are belong to every Object (like toString()).
In the previous example we just added another property to object that was automatically created. Instead we could have overriden the default empty object with a new one instead:
-
Pet.prototype = {
-
sayHello : function()
-
{
-
alert(this.hello);
-
}
-
};
You can even set the prototype to an be a new object created by another constructor. This is called prototype chaining and is the way related javascript objects can share implementation much like inheritance in a class based language:
-
function Cat()
-
{
-
…
-
}
-
Cat.prototype = new Pet();
Every constructor has a prototype property
Even built in constructors like String or Array. Libraries like prototype and ASP.NET ajax use this to add functions to the built in types like Array.reverse() or String.trim().
Here’s a simple example that adds a sheep function to all javascript string objects:
-
String.prototype.sheep = function()
-
{
-
return "baaah " + this;
-
-
-
}
-
var hello = "hello world";
-
alert(hello.sheep());
Why is this important?
The practical reason why this is important is sharing single a method between all objects uses less memory than having a separate copy for each object. This can be a big advantage when working on a complicated web application with lots of objects.
The javascript object prototype also enables you use some interesting coding patterns like inheritance and object cloning to more easily share implementation between similar objects in a similar way to how you would use classes to do this in a class based language.
What’s next?
Prototype chaining is used to build new types of objects based on existing ones. It has a very similar job to inheritance in a class based language.
This article is part of a set of related posts about How javascript objects work.







Comments
hi Helen,
I’ve really enjoyed all this info you’ve put together on using JS. You write clearly and break down these concepts into thought chunks I understand. Since I know I am sometimes/often guilty of trying to convey too many concepts at one time, I don’t feel surprised by how common that practice is among coders and instead simply appreciate when I find the contrast.
Anyway, thought you might like to enhance your comment fields with tabs. Makes it easier for us coders to indent our code when we’re discussing.
http://teddevito.com/demos/textarea.html
Thanks Ted, I’m glad you’ve found it useful. :) The tabs in the comment field is a good idea. I’ll have to look into it!
Hi,
I’m not sure but I thought, that you can’t add methodes to existing classes like “string” or “node” in IE. Tell me if I’m wrong!
You can extend built in javascript objects like string in all browsers, even IE:
String.prototype.trim = function()
{
alert(“this function can trim a string object”);
}
var moo = “Hello world”;
moo.trim();
In Firefox, Safari, Chrome and Opera you can also extend HTML elements:
window.onload = function()
{
HTMLElement.prototype.moo = function()
{
alert(“Calling the HTML Element’s moo function”);
}
document.body.moo();
}
In IE (I just tested in IE8) you can’t extend the DOM objects because they’re not part of javascript, they’re really COM objects.
You can see the full example here: http://helephant.com/wp-content/uploads/2009/01/built-in-prototype.html
Ah ha! You can also extend the prototype of DOM objects in IE8: http://msdn.microsoft.com/en-us/library/dd282900(VS.85).aspx
Using Pet.prototype.sayHello= as opposed to this.sayHello= in the Pet example makes no difference to the end result and it is simpler to use this.sayHello=. Your justification for the former is saving memory but I wonder if that is important these days. Why complicate the matter further when programming is complicated enough already.
I also wonder if using Pet.prototype.sayHello= does actually save memory. I tested the rufus object on my system and it still included the sayHello method even if Pet.prototype.sayHello= was used.
Appreciate your article that make me capable of appreciating the simplicity and ingenuity of the design of javascript.
@John,
At least per my experiment in Firebug js console, prototype is shared to all instances.
I think another advantage of prototype is it exhibits the dynamic essence of javascript. Of course you can declare properties and functions with a constructor, but prototype enable you modify the common behavior of a ‘class’ of objects LATER.
To John Middlemas:
The Pet.prototype.sayHello example is simplistic to illustrate the idea. In the real world, javascript classes are much more significant in size, and can have rather large methods. If I have 1000 instances of an object, without prototype I would have 1000 instances of that large method as well. With prototype, the sayHello method will be included but only as a reference to the single existing method, which translates to a significant reduction in memory usage.
I’m all for simplified programming, but would have to defend prototype as a necessity.
I also think that whether you want to use prototypes or not, it’s good to understand what they are so you can make an informed choice and so you can understand what other people’s code is doing.
I think it’s particularly helpful if you are using a Javascript library because many of them use prototypes to simulate classic inheritance and if things go wrong it’s really hard to debug without understanding what’s going on.
That said.. I should update my article with a more convincing argument in the object prototype’s favour. :)
Thanks for the lucid article. It helped me assure myself I was right when I was puzzling over some javascript.
You ma’am , are awesome. I have been looking for good javascript knowledge but all I could find was “How to create slideshows” ,”How to show alerts” and this kind of immature stuff. I started reading Douglas Crockford’s “Javascript – The good parts”, it is an amazing book. I just needed clarification for prototypes and constructors and your articles were are a great help.
Thank You
Hi Helen,
Very well done JS object prototype article. Keep up the good work.
Trackbacks