TypeScript to end your woes of prototype

Out of a coffee discussion, came out a fact that many people still don’t know the correct answer of this simple question of how to correctly construct an object in Javascript? Prototype based languages like javascript, has no concepts of class, but they have concepts of objects, functions and method. So what is the difference between a function and a method? Method is bound to the instance of the class in which it is defined, where as a function is stand-alone and is bound to nothing. You can define objects in such a way that they look like class, and have constructor etc. Every function can be a constructor by calling it with keyword ‘new’. Often people write this code, see if you find anything wrong with it.

function Person(name, age){
		this.name = name;
		this.age = age;
		this.sayName = function () {
			alert ('The Name is: ' + name);
		};
	}

	var say = function ()
	{
		var person1 = new Person('Aman',12);
		person1.sayName();

		var person2 = new Person('Neha',14);
		person2.sayName();
	}

If you have paid little attention to detail then you will notice the problem in above code. The problem is that every instance of Person will have their own copy of ‘sayName’ function. Not a good idea, if you have 25 functions and there are 100 objects then you are left with 2500 function copies.

Did’t I say, JavaScript does not support classes or methods, then what does ‘this’ keyword point to? The ‘this’ keyword actually points to the object within which the function is executed. JavaScript lets you pass functions around and assign them to other object’s properties, the object which contains a function may change throughout program execution and that is why the ‘this’ reference may also change depending on function context.

Coming back to our example, see the below picture, you will see two copies of ‘sayName’ in debugger.

prototype1

You can solve this problem by using “combination of prototype and constructor pattern”. Define the function on prototype. Now with this code, the function is defined on the common object prototype.

function Person(name, age){

		this.name = name;
		this.age = age;
	}

	Person.prototype = {
		constructor: Person,
		sayName : function () {
			alert ('The Name is: ' + this.name);
		}
	}

	var say = function ()
	{
		var person1 = new Person('Aman',12);
		person1.sayName();

		var person2 = new Person('Neha',14);
		person2.sayName();

	}

Now, what is prototype? Each function is created with a prototype property, which is an object containing properties and methods that should be available to instances of a particular reference type. You get that? Every function, aka every object (Remember, functions are objects) will have a prototype property, which in turn is an object which holds all the properties and methods that should be available to all the instance of object.

The object is actually a prototype for the object to be created once the constructor is called. The benefit of prototype is its properties and methods are shared among all the object instances. All the prototypes has an automatic property called constructor that points back to the function on which it is a property. Look at the below picture, now it shows only prototypes of objects have the functions, so no more extra copies of functions.

prototype2

The __proto__ property is an accessor property (a getter and setter function) that exposes the internal [[Prototype]]. The __proto__ property is deprecated and should not be used. Prefer Object.getPrototypeOf instead of __proto__ getter to determine the [[Prototype]] of an object. According to ECMA standard it is suppose to be a hidden property though most vendors allow it to be accessed and modified.

So, the correct way to define an object in javascript is to use prototype. However, people who come from different language background does not like this syntax. The function body is defined separately, then methods defined on prototype etc. Enter typescript to end your woes of prototype business. Here is the code written in TypeScript.

 class Person {

    name: string;
    age: number;

     constructor(name: string, age: number) {
        this.name = name;
        this.age = age;
    }

    sayName() {
        alert('The Name is: ' + this.name);
    }
 }

The above typescript is simple, easy to read, and you don’t see prototype. You don’t need to know that instance methods should be defined on prototype and other properties should be on object itself etc. Below there is an example that shows how the above code will automatically be translated into javascript as follows:

 var Person = (function () {
     function Person( name, age) {
         this.name = name;
         this.age = age;
     }

     Person.prototype.sayName = function () {
         alert ('The Name is:' + this.name);
    };
    return Person;
  }) ();

Check this post to  know more about typescript.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s