Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 11

Exploring OOPS - JavaScript Style: Part 1 -

Encapsulation

Introduction
This article, 1st Part in the series of 3-article, starts discussion on OOPS implementation in
JavaScript.

Note: This article is an adaption (may be a mirror) of the article originally posted at Edujini™
Eduzine™ here.

All the three articles of the series:

1. Encapsulation at edujini_005_JavaScript_OO.aspx.
2. Inheritance at edujini_006_JavaScript_OO.aspx.
3. Polymorphism at edujini_007_JavaScript_OO.aspx.

Fundamentals
Obect Oriented Programming - as defined by Grady Booch - stands on three pillars:

 Encapsulation
 Inheritance
 Polymorphism

Here, we explore how all three - Yes! All Three Pillars of OOPS - are implemented in JavaScript.

Getting Started
To get started, it is assumed that you are already familiar with basic JavaScript. If not you can
look on the web for some tutorials on JavaScript 101 tutorials or the like. To be specific, the
following fundamentals are assume:

 Declaring variables - var keyword.


 Basic data types supported - Object, Array, Boolean, Number, String and Function.
 Writing functions - well, you got to be really very strong in functions! Look here for all insights
about JavaScript functions.

4-Sutras while working with JavaScript


While working with JavaScript, always keep in mind the following, as Gaurav Vaish (yes, that's me)
calls them, "4-Sutras":
1. All data-types are infinitely flexible.
2. All objects (references; instances) are infinitely extensible.
3. Objects are associative arrays.
4. It's all about functions.

"In JavaScript, whenever you run into any problem related to implementation or structuring of
the code, these four sutras will help you out", I say.

Encapsulation
Encapsulation - in simplest terms - can be defined as putting the related items together.
Structures in C is a way to implement encapsulation. Classes in C++, Java, C# etc is another way
to implement encapsulation.

Let us see how encapsulation is implemented in JavaScript.

Welcome, Functions!
Gaurav's 4th Sutra comes into action here - "It's all about functions".

Let us define a data-type UserProfile that encapsulates the following three items:

1. username: Property to hold the username of the user.


2. password: Property to hold the password of the user.
3. authenticate: Method to authenticate the user. Returns true if successful, false otherwise.

Let us implement the UserProfile with a constructor that takes the two properties as
parameters and initializes itself. Create a file UserProfile.js (strictly speaking, the filename
doesn't really matter) with the following code.

Hide Copy Code

/**
* (C) 2008, Gaurav Vaish, Edujini Labs Pvt Ltd
* http://www.edujini-labs.com
*/

function UserProfile(username, password)


{
this.username = username;
this.password = password;

this.authenticate = function()
{
if(this.username == 'gvaish' && this.password == 'edujini')
{
return true;
}
return false;
}
}
Notice the use of this keyword. Does it remind you of someting? Yes! You got it
right... function is the way to implement the concept of class, or to speak - encapsulation.

Test Case
Ok... so, how do we use this new data-type that we just defined? Let's create a HTML file that will
serve as the playground for our case-studies around the UserProfile. Create a
file UserProfile.html (again, filename is not important at all) with the following content:

Hide Copy Code

1 <html>
2 <head>
3 <title>OOPS in JavaScript- Encapsulation</code>

Analysis
Let's just analyze the code that we just wrote.

We have designed a simple form comprising of inputs for username and password, and a button
to trigger validation.

The function validateUser defined at line 11-21 triggers the validation by extracting the values
of username and password (lines 13-14).

At line 18, UserProfile is instantiated. Notice a very important thing - the function definition
has been used as the constructor. Yes! That's where functions are so important in JavaScript. The
functions in JavaScript are higher order functions (similar to that in Smalltalk), that can be used to
retain the state.

At line 19, we invoke the method authenticate that returns a value true or false depending
upon what we enter in the form.

So, go ahead and try out with different combinations of username and password, and checkout
the results!

Summary
In this article we learnt how encapsulation is implemented in JavaScript. To summarize, we
explored the following:

 Encapsulation in JavaScript.
 Use of this keyword within the type definition.
 Defining properties and methods in JavaScript.
Moving forward...
The next step is look at the next articles on Inheritance and Polymorphism in JavaScript.

Exploring OOPS - JavaScript Style: Part 2 -


Inheritance

Introduction
In the second article of the series of "Exploring OOPS - JavaScript Style", we look at how
inheritance is implemented in JavaScript.

Note: This article is an adaption (may be a mirror) of the article originally posted at Edujini™
Eduzine™ here.

All the three articles of the series:

 Encapsulation at edujini_005_JavaScript_OO.aspx.
 Inheritance at edujini_006_JavaScript_OO.aspx.
 Polymorphism at edujini_007_JavaScript_OO.aspx.

Inheritance can be described as reusability by virtue of heritage. An inherited data-type


automatically obtains the functionality defined in the data-types from which it inherits.

JavaScript supports single inheritance, i.e., you can inherit from maximum one type. Also, it does
not support the concept of interface introduced in languages like Java, C# to support multiple
inheritance. In JavaScript what we have is instance-inheritance (or runtime inheritance) rather
than class-inheritance (or compile-time inheritance) making inheritance more powerful than
probably any other language around (barring the ones like Smalltalk)!

Downloads
The downloads are available in the Downloads area.

Getting Started
In Part 1, we defined UserProfile with username and password. In this article, we
create EmployeeProfilethat inherits from UserProfile and adds employeeID. It also
reimplements (override, if you like to use that word) authenticate method.
EmployeeProfile Definition
We start with defining EmployeeProfile with employeeID besides earlier properties. Create a
fileEmployeeProfile.js with the following code:

Hide Copy Code

/**
* Part of the Eduzine (http://eduzine.edujini-labs.com) Articles.
*
* Downloads available at http://downloads.edujini-labs.com
*
* (C) 2008, Edujini Labs Pvt Ltd
* http://www.edujini-labs.com
*/

function EmployeeProfile(username, password, employeeID)


{
this.username = username;
this.password = password;
this.employeeID = employeeID;
}

The next step is to mark it inherited from UserProfile. For this, we need to work with the
property prototypethat is always available to us whenever we declare a function. (Note that all
functions can be used as constructor.) Add the following additional code at the end of the code
above:

Hide Copy Code

EmployeeProfile.prototype = new UserProfile();

Note the following:

 The inerhitance is defined not through the data-type UserProfile but through its instance.
 The instance of UserProfile has been created without passing any parameters to the method.

Testing the Definition


So, it's time to test the definition so far... Let's create EmployeeProfile.html with the
following content:

Hide Shrink Copy Code

<html>
<head>
<title>OOPS in JavaScript- Encapsulation</code>
<script language="'javascript'" type='text/javascript' src='UserProfile.js'></script>
<script language="'javascript'" type='text/javascript'
src='EmployeeProfile.js'></script>
<script language="'javascript'" type='text/javascript'>
/**
* Part of the Eduzine (http://eduzine.edujini-labs.com) Articles.
*
* Downloads available at http://downloads.edujini-labs.com
*
* (C) 2008, Edujini Labs Pvt Ltd
* http://www.edujini-labs.com
*/
function validateUser()
{
var eid = document.getElementById('i').value;
var uname = document.getElementById('u').value;
var pwd = document.getElementById('p').value;

var e = document.getElementById('result');

var ep = new EmployeeProfile(uname, pwd, eid);


e.innerHTML = 'Username: ' + ep.username
+ '<br/>Password: ' + ep.password
+ '<br/>EmployeeID: ' + ep.employeeID
+ '<br/>Authenticate: ' + ep.authenticate();
}
</script>
</head>
<body>
Employee ID: <input type='text' name='i' id='i' />
<br/>
Username: <input type='text' name='u' id='u' />
<br/>
Password: <input type='password' name='p' id='p' />
<br/>

<button onclick='validateUser(); return false;'>Login</button>

<div id='result'></div>

</body>
</html>

I think the code is self explanatory. What we get is not only the three properties but also
automatic definition ofauthenticate method for EmployeeProfile. After all, that's that
inheritance is all about. In the definition ofEmployeeProfile, we never mention about it but it is
automatically available to it through its parent objectUserProfile.

instanceof Operator
We'll explore method overriding and other complex (unexplored, not mentioned so far) things in
a while. We take a short while to look at instanceof operator.

It is a binary operator. The left operand is the object-reference and the right operand is the
function-definition (data-type reference). The operator returns a boolean value
indicating whether the object is an instance of the corresponding type or not.

Hide Copy Code

if(ep instanceof UserProfile)


{
alert('ep is an instance of type UserProfile');
} else
{
alert('ep is NOT an instance of type UserProfile');
}

You can add this code to the method validateUser. In our case, it must return true.
Similarly, obj instanceof Object for any non-null value for obj will return true.

Method Reference and Optimization


And a very crutial item before we get back on to our main agenda.

Depending upon how we write the code, the methods may be loaded in memory multiple times.
Which is bad for the appliation. We do not want identical piece of code to be loaded in memory
multiple times. The code must be loaded only once and be executed in the context of the
corresponding object. What am I talking? Update the code for the method validateUser to as
follows:

Hide Copy Code

function validateUser()
{
var eid = document.getElementById('i').value;
var uname = document.getElementById('u').value;
var pwd = document.getElementById('p').value;

var ep1 = new EmployeeProfile(uname, pwd, eid);


var ep2 = new EmployeeProfile(uname, pwd, eid);

alert('Are references same? ' + (ep1.authenticate == ep2.authenticate));


}

You are bound to get a false! It hurts.

Everytime we instantiate EmployeeProfile (or even UserProfile for that matter), code for
the methodauthenticate is loaded into memory. Imagine if we have 1000 instances. Not only
the properties are loaded into memory 1000 times, but also the code for the method. It's just too
bad.

Let's fix this up...

Update the code for UserProfile to as follows:

Hide Copy Code

function UserProfile(username, password)


{
this.username = username;
this.password = password;
}

UserProfile.prototype.authenticate = function()
{
if(this.username == 'gvaish' && this.password == 'edujini')
{
return true;
}
return false;
}

Notice the use of prototype property once again. That holds the key! That's probably - The
Key property in JavaScript.

Now, execute the test case once again. ep1.authenticate == ep1.authenticate must
return true in this case! Detailed discussion around prototype is out of the scope of this article...
but will have one some time soon.

Method Overriding
Next, we explore how to override the method authenticate. Update the definition
of EmployeeProfile to as given below:

Hide Copy Code

function EmployeeProfile(username, password, employeeID)


{
this.username = username;
this.password = password;
this.employeeID = employeeID;
}

EmployeeProfile.prototype = new UserProfile();

EmployeeProfile.prototype.authenticate = function()
{
if(this.employeeID == 123 && this.username == 'gvaish'
&& this.password == 'edujini')
{
return true;
}
return false;
}

Go ahead and authenticate with various compbinations of


the employeeID, username and password. Hurray! The method has been overridden (using the
line of hierarchy of the object prototype).

The last thing that we see in method overriding is how to invoke the base-type method in the
sub-type method. Well, the solution again lies in prototype!

Let us define the business logic for an employee's authentication as follows:

1. It checks for the authentication results from UserProfile. If it has failed, the result is failure.
2. It additionally checks for employeeID.

This way we keep EmployeeProfile independent of how the UserProfile authenticates itself.
ModifyEmployeeProfile to as follows:
Hide Copy Code

function EmployeeProfile(username, password, employeeID)


{
this.username = username;
this.password = password;
this.employeeID = employeeID;
}

EmployeeProfile.prototype = new UserProfile();

EmployeeProfile.prototype._authenticate = EmployeeProfile.prototype.authenticate;

EmployeeProfile.prototype.authenticate = function()
{
if(this._authenticate())
{
return this.employeeID == 123;
}
return false;
}

Note that this is one of the various possible ways of achieving our target. We create a
reference _authenticateto the original authenticate method (but did we get it
from EmployeeProfile since we defined it inUserProfile - that's the magic of prototype in
JavaScript).

Rerun your test case... Wow! We get what we expect...

Summary
In this article we learnt how encapsulation is implemented in JavaScript. To summarize, we
explored the following:

 Inheritance in JavaScript.
 Use of prototype property to mark inheritance.
 Defining new methods in the inherited type.
 Override existing methods, optionally also calling the original method.
 instanceof operator to check the underlying data-type inheritance hierarchy.

Exploring OOPS - JavaScript Style: Part 3 -


Polymorphism

Introduction
In the third and last article of the series of "Exploring OOPS - JavaScript Style", we look at
polymorphism in JavaScript.
Note: This article is an adaption (may be a mirror) of the article originally posted at Edujini™
Eduzine™ here.

All the three articles of the series:

 Encapsulation at edujini_005_JavaScript_OO.aspx.
 Inheritance at edujini_006_JavaScript_OO.aspx.
 Polymorphism at edujini_007_JavaScript_OO.aspx.

Polymorphism literally means "multiple forms". In OOAD, it means that an object reference can
take different behave differently depending upon the scenario.

Technically, there are two types of polymorphism - compile-time polymorphism and runtime
polymorphism. One of the ways to implement compile-time polymorphism is method
overloading while runtime polymorphism can be implemented by method overriding.

Downloads
The downloads are available in the Downloads area.

Compile-time Polymorphism
All functions in JavaScript are overloaded by default. Surprised, isn't it? Let's take a simple code
below for analysis:

Hide Copy Code

<html>
<head>
<title>OOPS in JavaScript - Polymorphism</code>

For the time being, do not worry about the actual results. What is more important is that
invocation of these methods do not result in any error whatsoever! And that's because all
methods in JavaScript are, by default, overloaded. And did somebody say - that's compile-time
polymorphism?

What we provide in the parameter-list to a JavaScript function is just names to those parameters
so that it is convenient to access them. All parameters passed to a function are available through
an automatically-created local-variable arguments. Let's redefine the same method to access all
parameters passed to it, convert each into number and return the their sum (if they are not NaN).

Hide Copy Code

<html>
<head>
<title>OOPS in JavaScript - Polymorphism</code>
arguments if of the type Arguments. Apart from other properties, one critical thing to which it
provides access to is all the parameters passed to the function while invoking it.

Though it may sound unusual for those who are used to working with languages like C, C++,
Java, C# etc but probably they can relate this to varargs. And the same mechanism is available
for instance methods (for custom types) as well.

Runtime Polymorphism
Method overriding? Haven't we already discussed this in the previous article while discussing
about inheritance?

Summary
In this article we learnt about polymorphism in JavaScript.

You might also like