1024px-Flatirons_Winter_Sunrise_edit_2

##Introduction

In this mini-series we are reviewing some of the various ways you can create objects in JavaScript.

Thus far we have covered the Constructor Pattern and we will continue to cover the following patterns

* The Prototype Pattern
* The Constructor and Prototype Pattern
* The Object.create() Pattern

##The Prototype Pattern

As we’ve already mentioned, JavaScript is full of objects! Each of these object has a special property that references another object known as it’s “prototype”. A C# developer might think of this “prototype” as a base class that your object extends.

Note: It is not the focus on this series to investigate the various types of inheritance in JavaScript. That will be reserved for another mini-series.

In many implementations of ECMAScript (JavaScript’s official name) you can access an object’s prototype using the “__proto__” property. The property is currently accessable in Chrome, Safair, and Firefox, but unfortuantely it is hidden in other implementions. Despite the properties cross-browser issues, we will continue to refer to “__proto__” in our diagrams and discussions. It is also noteworthy that there is new standard way to access an object’s prototype as of ECMAScript 5, which is to use the “Object.getPrototypeOf” function. Unfortunately, this function is not yet implemented in all browsers either.

##Taking a Look at Native Prototypes

In order to better understand what a prototype really is and to appreciate it’s value, let’s take a look at one of the native JavaScript types.

The array is a commonly used and powerful JavaScript type. You can push values onto an array, sort the underlying items, and slice and dice it to your heart’s content.

When you create an array, the functions that you are actually enjoying are not stored in the object itself, but instead it has a prototype that references another object which contains these methods.

Take for example, the following code.

[js] var listOfLanguages = [ “C#”, “ColdFusion”, “F#”, “Java”, “JavaScript”, “PHP” ];
[/js]

If you were to look at the variable in the Google Chrome Watch Expression you will see that these function are hosted off of the object’s “__proto__”.

Screenshot A

You might diagram this relationship as the following:

Diagram D

##Defining My Own Prototype

Let’s start by taking the same C# class example that we used in the Constructor Pattern post and re-write it using the Prototype Pattern.

[js] using System;

public class Skillet {
public string Ingredient { get; set; }
public int Quantity { get; set; }

public Skillet( string ingredient, int quantity )
{
this.Ingredient = ingredient;

this.Quantity = quantity;
}

public void fry()
{
Console.WriteLine( “Frying ” + this.Quantity + ” ” + this.Ingredient );
}
}

public class Runner
{
public static void Main()
{
Skillet mySkillet = new Skillet( “bacon strips”, 2 );

mySkillet.fry();
}
}
[/js]

The Prototype Pattern will look considerably different from the Constructor Pattern as seen below.

[js] function Skillet() {}

Skillet.prototype.ingredient = “”;
Skillet.prototype.quantity = 0;
Skillet.prototype.fry = function() {
console.log( “Frying ” + this.quantity + ” ” + this.ingredient );
};

var mySkillet = new Skillet();
mySkillet.ingredient = “bacon strips”;
mySkillet.quantity = 4;

mySkillet.fry();
[/js]

In this partern, we still have a constructor, but it is empty. The majority of our definition will reside off of the constructor’s prototype.

A visual representation of our custom type looks like the following:

Diagram E

Some things you might noticed in the Prototype Pattern is that:

* We still use a Constructor, although empty, and maintain the first letter capitalized naming convention.
* The functions and properties are assigned onto the contructor’s prototype
* You continue to use the “new” operator to create the new instance.
* You set the properties of the object after it’s creation since nothing is passed to the Constructor (we will address this in the next Pattern)

At first glance, this might not seem any better than the Constructor Pattern, however, if we digg deeper we find that this is a very powerful technique.

##The Power and Dynamic Nature of Prototypes

As a C# developer you are familiar with the concept of overriding methods or properties when modifying an abstract or virtual implementation. The following code snippet defines a Skillet class with properties and a fry method. Then we define another BaconSkillet class that extends the base Skillet and we override the fry method;

[js] using System;

public class Skillet
{
public string Ingredient { get; set; }
public int Quantity { get; set; }

public Skillet() {
this.Ingredient = “sticks of butter”;
this.Quantity = 2;
}

public virtual void fry()
{
Console.WriteLine( “Frying ” + this.Quantity + ” ” + this.Ingredient );
}
}

public class BaconSkillet : Skillet {
public BaconSkillet() : base() {}

public override void fry()
{
base.fry();
Console.WriteLine( “Frying ” + this.Quantity + ” crispy ” + this.Ingredient );
}
}

public class Runner
{
public static void Main()
{
Skillet genericSkillet = new Skillet();
genericSkillet.fry(); //Frying 2 sticks of butter

BaconSkillet baconSkillet = new BaconSkillet();
baconSkillet.Quantity = 4;
baconSkillet.Ingredient = “bacon strips”;
baconSkillet.fry(); //Frying 4 bacon strips /n Frying 4 crispy bacon strips
}
}
[/js]

https://ideone.com/2VRVg

You can also do something very similar in the JavaScript language, but in this case you can do it at runtime! JavaScript is dynamic, so we can modify exiting functions or properties or add new ones after we create our objects.

You can also modify a prototype at runtime. By doing so all the objects that refer to the prototype will be updated as well. If you think about it, the prototype is really just a reference to another object. So, by changing the shared prototype you are changing all the created objects.

For example, in the following Skillet I have provided default values to the ingredient and quantity properties as well as provided a default fry function. When you create a new Skillet object it will inherit these values and functions unless you override them with another value. You are esessionally masking the prototype values and using a value specific to the object.

Note: This is a work in progress. There are still some issues that we need to address in the following code, but I don’t want to cover too much at one time and I think it is valuable to see the progression and the possible issues of the following code.

[js] function Skillet() {}

Skillet.prototype.ingredient = “sticks of butter”;
Skillet.prototype.quantity = 2;
Skillet.prototype.fry = function() {
console.log( “Frying ” + this.quantity + ” ” + this.ingredient );
};

var emptySkillet = new Skillet(),
eggSkillet = new Skillet(),
hashBrownSkillet = new Skillet(),
baconSkillet = new Skillet();

//Inherits both ingredient and quantity from prototype
emptySkillet.fry(); //Frying 2 sticks of butter

//Override ingredient from prototype
eggSkillet.ingredient = “eggs”;
//Inherits quantity of 2 from the prototype
eggSkillet.fry(); //Frying 2 eggs

hashBrownSkillet.ingredient = “hash browns”;
hashBrownSkillet.quantity = 3;
hashBrownSkillet.fry(); //Frying 3 hash browns

//Overrides ingredient and quanity from the prototype
baconSkillet.ingredient = “bacon strips”;
baconSkillet.quantity = 4;
baconSkillet.fry = function() {
Skillet.prototype.fry.call(this);
console.log( “Frying ” + this.quantity + ” crispy ” + this.ingredient );
};
baconSkillet.fry(); //Frying 4 bacon strips /n Frying 4 crispy bacon strips
[/js]

Figure F

[js] //Change the quantity property and fry function on the prototype
Skillet.prototype.quantity = 2000;
Skillet.prototype.fry = function() {
console.log( “Frying up a FEAST of ” + this.quantity + ” ” + this.ingredient );
};

//Will inherit ingredient & quantity property and new fry function off of the prototype
emptySkillet.fry(); //Frying a FEAST of 2000 sticks of butter

//Will inherit quantity property and new fry function off of the prototype
eggSkillet.fry(); //Frying a FEAST of 2000 eggs

//Only inherits new fry function, because the ingredient & quantity properties were overridden
hashBrownSkillet.fry(); //Frying 3 crispy hash browns

//Remove the quanity property so that the updated prototype can bleed through.
//Still calls overriden fry() method, but it calls the updated prototype fry method
delete baconSkillet.quantity;
baconSkillet.fry(); //Frying a FEAST of 2000 bacon strips /n Frying 2000 crispy bacon strips
[/js]

Figure G

##Your Data Is Not Your Own

Something you should be aware of using this pattern is that any propery on the prototype will be shared across all object instances. This could provide some confusing scenarios if you are not aware of this. Let’s start with another example prototype and examine it’s output.

[js] function Skillet() {}

Skillet.prototype.ingredients = [ { name: “sticks of butter”, quantity: 2 } ];
Skillet.prototype.fry = function() {
var length = this.ingredients.length, index, ingredient;

for ( index = 0; index < length; index++ ) {
ingredient = this.ingredients[index];
console.log( “Frying ” + ingredient.quantity + ” ” + ingredient.name );
}
};

var emptySkillet = new Skillet(),
baconSkillet = new Skillet();

emptySkillet.fry(); //Frying 2 sticks of butter

baconSkillet.ingredients.push( { name: “bacon strips”, quantity: 4 } );
baconSkillet.fry(); //Frying 2 sticks of butter /n Frying 4 bacon strips

//By adding bacon to the baconSkillet’s ingredients prototype,
//we also added bacon to the emptySkillet since it shares the same prototype.
//This may or may not be what you intended
emptySkillet.fry(); //Frying 2 sticks of butter /n Frying 4 bacon strips
[/js]

http://jsfiddle.net/Z7Xbr/5/

Figure H

In the prvious example, we created an emptySkillet and a baconSkillet. Both skillets have 2 sticks of butter in then by default as defined in their prototype. The baconSkillet adds 4 strips of bacon to it’s prototype, but by doing so it is actually adding bacon to the emptySkillet as well. So, after we add bacon to the baconSkillet we see that it was also added to the emptySkillet when we call the fry() method again.

Note: The next article in this sceries will show how you can get around this possibly confusing and undesired behavior.

##Pros of This Technique

* You can provide default properties and functions that will be used by all your objects
* You can override these default properites or functions with an object specific version
* Changing the prototype at runtime will apply to all objects that were created with that prototype

##Cons of This Technique

* The syntax of the prototype looks unfamiliar to a C# developer
* We lost the ability to pass values to the constructor to use as initial values
* Since our properties are declared on the prototype they will be shared across all objects. This may or may not be what you want.

##Conclusion

The Prototype pattern is probably new to most C# developers, but it provides similar concepts that they are used to in object oriented programming such as inheritance, property and method overriding, etc. This pattern is also common and you will find it often when searching the internet. You should be familiar with this pattern and know it’s strengths and weaknesses as we pointed out in this article.

In the next section we are going to introduce the concept of combining JavaScript Constructors and Prototype. Each pattern has it’s strengths and weaknesses, but we can solve some of those weaknesses by combining them both.