C# Corner: Creating JavaScript Objects Part 2 – Prototype

By |March 28th, 2015|Categories: JavaScript|

##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.

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.

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

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;

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.

Figure F

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.

https://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.

Kyle Pennell
Kyle Pennell is the editor of appendTo.com.