Taking a close look at inheritance and closures in Javascript

Let’s play with inheritance and closures in Javascript. Take a look at the following javascript code:

function BaseClass(){
	var id=200;
	this.Id=function(){
		return id;
	}
}

function ChildClass(){
	var id=500;
}

ChildClass.prototype = new BaseClass();
var childObject=new ChildClass();

In Javascript, inheritance is achieved using prototype. When we try to access any member on Javascript object, it first tries to search for the member within that object. If the member is found, then its accessed otherwise it tries to search for that member in its prototype object.

We make BaseClass the parent class of ChildClass with the following instruction:

ChildClass.prototype = new BaseClass();

Notice that ChildClass does not have a method called ‘Id’. When we make a call to method ‘Id’ on childObject, it will see that ChildClass does not have ‘Id’ method and so will take it from its prototype object which is nothing but the object of BaseClass.

Based on this knowledge, what do you think will be the output of the following instruction?

childObject.Id()

If you think it should be 500, then you are wrong. The correct answer is 200. This happens due to what is known as Closures. According to a tutorial on javascript closures by Morris Johns:

“a closure is the local variables for a function – kept alive after the function has returned”

To understand how this works in our case, let’s try to understand how javascript actually executes a call to the method ‘Id’ on childObject.

As childObject does not have a method called ‘Id’, it takes that method from its prototype and then executes it. You can imagine that Javascript performs the following steps to execute a call to the method ‘Id’ on childObject.

childObject.Id = ChildClass.prototype.Id;
childObject.Id();

But does its mean that in Javascript, it’s not possible to override the values from base class/object at all? Well, It is possible by making a small change to our code. Javascript has a keyword called ‘this’. The ‘this’ keyword points to the object in which the method being called is present. For more information on ‘this’ keyword, refer to the article ‘The this keyword’.

In our current code, we are defining a variable using keyword ‘var’ which makes it local to the function in which it is defined. Due to this, closure comes into picture and call to the method ‘Id’ always prints the value from the BaseClass. To solve this problem, we need to refer to the variable ‘id’ using ‘this’ keyword. This will tell our method to use the value from the object in which the method has been placed. In this way, when the method is placed in ChildClass object, it will print the value of ‘id’ from ChildClass and not from BaseClass. Thus, the modified code which allows overriding is given below:

function BaseClass(){
	this.id=200;
	this.Id=function(){
		return this.id;
	}
}

function ChildClass(){
	this.id=500;
}

ChildClass.prototype = new BaseClass();
var childObject=new ChildClass();

Binding HTML Form Fields To Javascript Objects

Consider that I have a object called ‘person’ with a property called ‘Name’ which returns me the name of a particular person. I want to assign this object property to a form element such that:

  1. The form element will display the value of object property (In our case, the value of person.Name)
  2. If I change the value in form, then it should automatically get assigned to the object property

In C#, it could be done by using the following piece of code:

nameTextBox.DataBindings.Add("Text", person, "Name");

I really like the way DataBinding works and would really like have something like this when I’m working on web applications to bind a object property to input elements in HTML forms. So I decided to write a small javascript that would allow me to bind object properties to form elements. For example, I wanted to write something like this:

<input type="text" object="person" property="firstName" />

Thanks to the power of Javascript and prototype library, I was able to use data binding in html forms using code:

function initializeFormBinding()
{
	var formElements = document.getElementsByTagName('input');
	$A(formElements).each(function(formElement)
				{
					Element.extend(formElement);
					initializeFormElement(formElement);
				});
}
 
function initializeFormElement(formElement)
{
	if (!(formElementHasObjectAttribute(formElement) &amp;&amp; formElementHasPropertyAttribute(formElement)))
		return;
	var objectName = getAttributeValue(formElement,'object');
	var propertyName = getAttributeValue(formElement,'property');
	window.eval('formElement.value = '+objectName+'.'+propertyName);
	window.eval('formElement.onchange=function(){ '+objectName+'.'+propertyName+' = formElement.value; }');
}
 
function formElementHasObjectAttribute(formElement)
{
	return getAttributeValue(formElement,'object')!=null;
}
 
function formElementHasPropertyAttribute(formElement)
{
	return getAttributeValue(formElement,'property')!=null;
}
 
function getAttributeValue(element, attributeName)
{
	return element.readAttribute(attributeName);
}

Lets see how to use this: First, create a javascript object. For example:

var person = {};
person.firstName = '';
person.lastName = '';
person.age = '';
person.country = '';

After that call initializeFormBinding() function using onLoad attribute of body tag. For example:

<body onLoad="javascript:initializeFormBinding();">

Now, in each of your input elements, put the name of the object in ‘object’ attribute and name of property in ‘property’ attribute as follows:

<form>
First Name:
<input type="text" object="person" property="firstName" /><br>
Last Name:
<input type="text" object="person" property="lastName" /><br>
Age:
<input type="text" object="person" property="age" /><br>
Country:
<input type="text" object="person" property="country" /><br>
</form>

Thats it…. If you initialize properties of person object, you would see those values in respective form elements. On the other hand, if you modify the value in a particular input element then it would get reflected in the corresponding object property. Anybody is free to use this code in their applications.

Download a small example application..