JavaScript performance library

This article is a crash course of JavaScript prototypes.

What are prototypes in JavaScript ?

Prototype is an object from which other objects inherit their’s properties. You can think about a prototype object as a base object used to create final objects.

As an example, you can imagine a prototype object representing a generic car. This prototype has all of the elements that every car has, ie. engine, steering wheel, gearbox, brakes, etc. You can use this prototype to build more specific cars (objects) by extending the prototype’s properties. In example, you can insert to your newly built car (object) a faster engine and a lower suspension to create a sport car. You can add leather seats and other features to create a limousine. Instead of creating engine, brakes, and other base elements every time you create a new car (object), you can simply inherit those fundamental properties from a prototype.

Every object in JavaScript has it’s prototype (prototypes in JavaScript can have their own prototypes as well). The main, fundamental prototype, which is the core of all objects existing in JavaScript, is Object.prototype.

All objects created by object literal or with new Object() are directly linked to Object.prototype.

Some objects are not directly linked to Object.prototype. In example, an object created with new Date() is a prototype of Date.prototype (which is a prototype of Object.prototype). Beside this example, there are much more standard prototypes in JavaScript.

Creating prototypes in JavaScript

Creating an object that can be used as a prototype in JavaScript does not differ from creating any other object:

// Our prototype object
var myPrototype = {
    producer: "Oracle",
    product: "",
    version: "",
    getProductInfo: function() {
        return this.producer + " " + this.product + " " + this.version;
    }
};

To create objects using this prototype, we will create an elegant method that will perform this task:

// We will use this method to create objects using our own prototype
Object.createObject = function(prototypeObject) {
    var func = function () {}; // Create a blank function
    func.prototype = prototypeObject; // Assign the prototype object
    return new func(); // Return a blank object using provided prototype
};

Creating objects using our prototype:

// Create two objects using myPrototype prototype
var product_one = Object.createObject(myPrototype);
var product_two = Object.createObject(myPrototype);

Using prototypes in JavaScript

Objects inherit all of the properties and methods from their prototypes in JavaScript. Let us see if that’s true:

// Create two objects using myPrototype prototype
var product_one = Object.createObject(myPrototype);
var product_two = Object.createObject(myPrototype);

// Set properties for both of the objects
product_one.producer = "Sun";
product_one.product = "Solaris";
product_one.version = "7";

// Do not set "producer"; it will get inherited from the prototype
product_two.product = "Java";
product_two.version = "1.4";

// Execute getProductInfo() inherited from the objects' prototype
alert(product_one.getProductInfo()); // = Sun Solaris 7
alert(product_two.getProductInfo()); // = Oracle Java 1.4

Our objects indeed inherited the properties and methods of their prototypes in JavaScript. However, both of the objects have different product value. Let us investigate that.

Initially product_one is defined with all the properties and methods of it’s prototype. The producer equals to string “Sun”, product and version are empty strings, and getProductInfo is a function. Later in the code we assign new values to the inherited properties – they get overrided. Thus, for example, product does not equals to “Oracle”, but to “Sun”.

product_one.producer = "Sun";
product_one.product = "Solaris";
product_one.version = "7";
alert(product_one.getProductInfo()); // = Sun Solaris

After creation of product_two we override only two properties: producer and version. Since the producer property is untouched, it’s value is inherited from the prototype.

product_two.product = "Java";
product_two.version = "1.4";
alert(product_two.getProductInfo()); // = Oracle Java 1.4

Dynamic relationship of prototypes in JavaScript

In JavaScript, the prototypes have dynamic relationship to objects that inherit them.

Every change in a prototype object is present in every object that inherits this prototype.

As an example, we will add a language property to our myPrototype prototype:

// Let us try to access non-existent property
alert(product_one.language); // = undefined
alert(product_two.language); // = undefined

// Set a "language" property in the prototype
myPrototype.language = "english";

// Parameter "language" were not defined in the objects, but were dynamically inherited from the prototype
alert(product_one.language); // = english
alert(product_two.language); // = english

As you can see, the property language was dynamically added to our two objects without touching them directly – we added the property to the objects by adding it to the objects’ prototype.

Modifying standard JavaScript prototypes

You can not only create your own prototypes, but you can also modify existing prototypes in JavaScript that come as a standard.

Consider the following code…  JSFiddle link

// This string could use some trimming
var message = " I am a string that needs trimming!  ";

// trim() to the rescue!
alert(message.trim()); // properly trimmed

// Modifying the String object's prototype
String.prototype.trim = function() {
    return this + "; NO! I WILL NOT TRIM THIS STRING! YOU PAY ME WAY TOO LESS!";
};

// trim() to the rescue!
alert(message.trim()); // properl... wait what, wtf javascript!!
Modifying standard prototypes in JavaScript

Just try to modify the standard prototypes…

IMPORTANT: Never ever modify the prototypes of standard JavaScript objects. It’s an awful practice and other programmers will send you to hell if you ever do that. The code above is used only for educational purposes – never use it in your projects!

Example code

Example of the code discussed above.

Play with it for better understanding of prototypes in JavaScript. JSFiddle link.

// We will use this method to create objects using our own prototype
Object.createObject = function(prototypeObject) {
    var func = function () {}; // Create a blank function
    func.prototype = prototypeObject; // Assign the prototype object
    return new func(); // Return a blank object using provided prototype
};

// Our prototype object
var myPrototype = {
    producer: "Oracle",
    product: "",
    version: "",
    getProductInfo: function() {
        return this.producer + " " + this.product + " " + this.version;
    }
};

// Create two objects using myPrototype prototype
var product_one = Object.createObject(myPrototype);
var product_two = Object.createObject(myPrototype);

// Set properties for both of the objects
product_one.producer = "Sun";
product_one.product = "Solaris";
product_one.version = "7";

// Do not set "producer"; it will get inherited from the prototype
product_two.product = "Java";
product_two.version = "1.4";

// Execute getProductInfo() inherited from the objects' prototype
alert(product_one.getProductInfo()); // = Sun Solaris 7
alert(product_two.getProductInfo()); // = Oracle Java 1.4

// Let us try to access non-existent property
alert(product_one.language); // = undefined
alert(product_two.language); // = undefined

// Set a "language" property in the prototype
myPrototype.language = "english";

// Parameter "language" still does not exist in the objects, but is dynamicall inherited from the prototype
alert(product_one.language); // = english
alert(product_two.language); // = english

 Comments

Do you have any questions about prototypes in JavaScript? Post them in the comments section below.