Click here to Skip to main content
6,594,432 members and growing! (16,026 online)
Email Password   helpLost your password?
Web Development » Client side scripting » General     Beginner License: The BSD License

Exploring OOPS - JavaScript Style: Part 2 - Inheritance

By mastergaurav

This article, 2nd Part in the series of 3-articles, discusses Inheritance in JavaScript
Javascript, Architect, Dev, Design
Posted:19 Jun 2008
Updated:2 Aug 2008
Views:7,668
Bookmarked:8 times
Unedited contribution
Announcements
Loading...
 
Search    
Advanced Search
Add to IE Search
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
7 votes for this article.
Popularity: 2.54 Rating: 3.00 out of 5
1 vote, 14.3%
1
2 votes, 28.6%
2

3
1 vote, 14.3%
4
3 votes, 42.9%
5

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:

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 EmployeeProfile that 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 file EmployeeProfile.js with the following 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 prototype that 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:

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:

<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 of authenticate method for EmployeeProfile. After all, that's that inheritance is all about. In the definition of EmployeeProfile, we never mention about it but it is automatically available to it through its parent object UserProfile.

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.

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:

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 method authenticate 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:

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:

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. Modify EmployeeProfile to as follows:

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 _authenticate to the original authenticate method (but did we get it from EmployeeProfile since we defined it in UserProfile - 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.

License

This article, along with any associated source code and files, is licensed under The BSD License

About the Author

mastergaurav


Member
Gaurav lives in Bangalore, the Silicon Valley of India.
He is the Chief Technology Officer at Edujini Labs Pvt Ltd - a company that pioneers in Technology Trainings, Education using Technology and Technical Consultancy.
www.edujini-labs.com

His technical strength lies in having deep understanding of not one or two but dozens of enterprise frameworks.

Today, he is an independent guy:
- He is a programming language independent guy, well almost. He is proficient in C, C++, Java, C#, VB.Net, C++.Net, JavaScript, PHP, Tcl, Python, Ruby
- He is an OS independent guy, well almost. Has worked and developed at length on HP-UX, Linux (Redhat / Mandrake), Macintosh (9, 10.x), Windows (NT, 2000, 2003, XP, Vista), Solaris (8, 9, 10)
- He is a target independent guy, well almost. Has worked on thick clients (mainly desktops) as well as thin clients (mainly alternative platforms - Symbian, PalmOS, WinCE, WinXP Embedded, Linux Embedded)

Today, his thrust areas are Service Oriented Architecture (implementation expert in Java, .Net and PHP; integration with Mainframe and other legacy environments), Mobile Technologies and RFID.

His domain expertise include e-Learning, Anti-Piracy and Telecommunications.

Before co-founding Edujini™, he has worked in the capacity of Head, R&D at TeN, India and as Member, Technical Staff in R&D Team at Adobe Systems, India.

He holds a Bachelor's Degree (B. Tech.) from IIT Kanpur www.iitk.ac.in. His major was in EE with specialization in DSP (SSP).

His hobby is listening music, reading books (no, he can't read novels), photography and travelling.

Should you wish to talk to him, you can drop him a mail at gaurav[dot]vaish[at]gmail[dot]com. He generally responds within 24-48 hrs unless there is a compelling reason.

And yeah... here's his personal website:
http://www.mastergaurav.com

Smile
Occupation: Web Developer
Location: India India

Other popular Client side scripting articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
  (Refresh) 
-- There are no messages in this forum --

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 2 Aug 2008
Editor:
Copyright 2008 by mastergaurav
Everything else Copyright © CodeProject, 1999-2009
Web16 | Advertise on the Code Project