Lazy Inheritance is an approach intended to simplify writing OOP and provides support of prototype-based classes hierarhies, automatic resolving and optimizing classes dependencies.
JSINER (originated from JavaScript INheritance supportER) is a lazy inheritance implementation in JavaScript. JSINER page on SoftAMIS
One of the most powerful features offered by object oriented programming (OOP) is inheritance (or ability to create subclasses of particular class). On the one hand, JavaScript does not involve full-fledged support of classes such as one offered by C++ or Java.
On the other hand, it supports constructors which are able to create objects with the use of executing code which allocates storage for the objects and initializes these objects (or part of them) by assigning initial values to their properties. There are several possible ways to implement inheritance in JavaScript which are widely known and used. All of them have their own advantages and disadvantages.
"Lazy inheritance" is a design pattern used in JavaScript computer programming. It designates a postponed linking of an object with it's prototype (class) until it is needed. If used properly, such approach may increase efficiency, simplicity and flexibility of OOP based code written using JavaScript. Unlike of "classical" approach, it supports a "Lazy" way of inheritance implementation, since reference to parent class is invoked only at the moment of object instance creation. Basically, it's possible to say that instances of objects in such approach are created in "mixed" mode – on first invocation, an appropriate factory is used to modify object constructor prototype which is later used for subsequent object instances creation. Moreover, since "Lazy inheritance" is called only once at the moment of first object instance creation, it becomes possible to combine process of class prototype creation with resolving necessary dependencies of that class. In other words, the process of prototype construction also allows loading scripts (if ones were not loaded before) which particular class depends on.
Such approach to inheritance support has the following benefits:
But before digging into details, let's consider existing approaches used to implement inheritance.
JavaScript supports prototype-based inheritance. Each object constructor has a prototype property which is used to implement prototype-based inheritance and shared properties. Every object created by that constructor has an implicit reference to the prototype associated with its constructor. Such approach allows writing object oriented code in JavaScript.
The following fragment of code illustrates the common way to do this.
Let's assume that the following code is defined in person_cl.js JavaScript file and declares Person class:
/**
* Person’s constructor.
*/
function Person(aName)
{
this.fName = aName;
}
/**
* Here we define function which returns name of person and assign that function to
* Person class prototype.
*/
Person.prototype.getName = function()
{
return this.fName;
};
/**
* Here we declare function toString() that returns string representation of
* Person and assign that function to Person class prototype
*/
Person.prototype.toString = function()
{
return "Person: " + this.getName();
};
Let's declare another class, Employee which is inherited from Person one.
Let's assume that declaration of that class is placed to employee_cl.js JavaScript file:
/**
* Employee constructor
*/
function Employee(aName, aUID)
{
this.fName = aName;
this.fUID = aUID;
}
/*
* The inheritance definition.
* Here we create instance of Person and define that is inherited from Person,
* specify constructor for Employee and add superClass property to Employee class
*/
Employee.prototype = new Person();
Employee.prototype.constructor = Employee;
Employee.superClass = Person.prototype;
/**
* Here we declare function which returns UID of employee
* and assing it to Employee class prototype
*/
Employee.prototype.getUID = function()
{
return this.fUID;
};
/**
* Here we redeclare definition of toString() function which should be used by
* Employee class. Our declaration calls function from Person class and adds own Employee
* related information
*/
Employee.prototype.toString = function()
{
var person = Employee.superClass.toString.call(this);
return this.getUID() + ":" + person;
};
And this is sample HTML page which uses declarations of JavaScript object above:
<html>
<head>
<title>The Classical JavaScript inheritance test.</title>
// Order of references to scripts is important for proper code execution.
<script src="script/person_cl.js"></script>
<script src="script/employee_cl.js"></script>
</head>
<body>
<script>
var employee = new Employee('John Doe', 1212);
alert(employee);
</script>
</body>
</html>
Everything is seems to be quite straightforward in these examples so far.
However, such a "classical" implementation of inheritance has several disadvantages:
There is another way of creating several objects with the same structure in JavaScript offered by Douglas Crockford.
This approach assumes replacing prototype inheritance for prototypal using factory method instead of constructor.
Such a factory method is responsible for creation of new object instance.
Generally speaking, such approach does not represent pure inheritance, since it is oriented to creation JavaScript instances with the same properties, rather than classes.
However, it is intended to solve tasks which are close to ones solved by inheritance, and that's why we consider it there.
The following code snippet illustrates prototypal approach in more details.We declare the same example classes - Person and Employee. First, define Person using prototypal approach.
Let's assume that declaration of that class is placed to person_pp.js JavaScript file.
/**
* First, we define function which represents
* a factory for creation of Person objects
*/
function Person(aName)
{
var self = PROTOTYPAL.object();
self.fName = aName;
self.toString = Person.toString;
self.getName = Person.getName;
return self;
}
/**
* Here we declare function which will return name of Person and
* adding it to Person object
*/
Person.getName = function()
{
return this.fName;
};
/**
* Here we declare function which returns representation of the Person object and
* assign it to Person object
*/
Person.toString = function()
{
return "Person: " + this.getName();
};
Let's declare another class, Employee which is inherited from Person one.
Let's assume that declaration of that class is placed to employee_pp.js JavaScript file.
/**
* Here we define factory which will be used to
* create Employee that extend Person
*/
function Employee(aName, aUID)
{
// here we call method from library (prototypal.js)
// which supports prototypal inheritance
var self = PROTOTYPAL.object( Person(aName) );
self.fUID = aUID;
self.getUID = Employee.getUID;
self.toString = Employee.toString;
return self;
}
/**
* Here we declare function which returns representation of the Employee object and
* assign it to Employee object
*/
Employee.toString = function()
{
return this.getUID() + ":" + this.getName();
};
/**
* Here we declare function which will return UID of Employee and
* adding it to Employee object
*/
Employee.getUID = function()
{
return this.fUID;
};
And this is sample HTML page which uses declarations of JavaScript object above:
<html>
<head>
<title>The Prototypal JavaScript inheritance test.</title>
// We also need to include base prototypal related code
<script src="script/prototypal.js"></script>
// Order of references to scripts is important for proper code execution.
<script src="script/person_pp.js"></script>
<script src="script/employee_pp.js"></script>
</head>
<body>
<script>
var employee = new Employee('John Doe', 1212);
alert(employee);
</script>
</body>
</html>
Comparing to "classical" inheritance, the prototypal based approach has significant advantages,
but also several significant drawbacks:
JSINER (originated from JavaScript INheritance supportER) represents a JavaScript library intended to simplify writing object oriented code in JavaScript as well as managing external scripts dependencies.
JSINER’ offers approach which simplifies writing object oriented code with support of prototype based inheritance.
Unlike of "classical" approach, it represents a "Lazy inheritance" because reference to parent class is invoked only at the moment of object instance creation.
Basically, it's possible to say that instances of objects in such approach are created in "mixed" mode – on first invocation, an appropriate factory is used to modify object constructor prototype which is later used for subsequent object instances creation.
Moreover, since "Lazy inheritance" is called only once at the moment of first object instance creation, it becomes possible to combine process of class prototype creation with resolving necessary dependencies of that class. In other words, the process of prototype construction also allows loading scripts (if ones were not loaded before) which particular class depends on.
Such approach to inheritance support has the following benefits:
The following code snippets illustrate JSINER "Lazy inheritance" approach in more details.
Again, we declare the same example classes - Person and Employee.
First, we define Person.
Let's assume that declaration of that class is placed to person.js JavaScript file.
/**
* Constructor for Person class
*/
function Person(aName)
{
this.fName = aName;
}
/**
* Function which returns name of Person’s.
* That function is assigned to prototype of Person class corresponding by "classical" inheritance.
*/
Person.prototype.getName = function()
{
return this.fName;
};
/**
* Here we define function which returns string representation of Person
* assign it to prototype of Person class
*/
Person.prototype.toString = function()
{
return "Person: " + this.getName();
};
Now we illustrate how Person may be extended using couple of examples.
This example is quite basic and illustrates only the way how "pure inheritance"
should be supported via JSINER (without resolving dependencies between classes and required script files).
Here we assume that the code below is placed to employee1.js file.
/**
* Here we define constructor for Employee class and declare that Employee class
* inherits Person one
*/
function Employee(aName, aUID)
{
// lazy inheritance calling
var self = JSINER.extend(this, "Person");
self.fName = aName;
self.fUID = aUID;
return self;
}
/**
* Here we define function which return UID of employee and assign it to
* prototype of Employee class.
* This is exact approach as one used by "classical" inheritance
*/
Employee.prototype.getUID = function()
{
return this.fUID;
};
/**
* Here we define function which returns string representation of
* Employee object and assign it to Employee class prototype (as if classical approach is used).
* Our implementation combines/ string representation of Person object
* and own data from Employee class
*/
Employee.prototype.toString = function()
{
var person = Employee.superClass.toString.call(this);
return this.getUID() + ":" + person;
};
And this is sample HTML page which uses declarations of JavaScript object above:
<html>
<head>
<title>The JavaScript Lazy inheritance test.</title>
// We need to include reference to JSNIER code
<script src="script/jsiner.js"></script>
// Now it's not necessary to maintain order of scripts loading manually.
<script src="script/employee1.js"></script>
<script src="script/person.js"></script>
</head>
<body>
<script language="JavaScript1.2">
var employee = new Employee('John Doe', 1212);
alert(employee);
</script>
</body>
</html>
During execution of example of code listed above, lazy inheritance is called only once for f
irst creation of Employee instance.
It is not necessary to keep proper order of script files declaration in HTML document.
This example illustrates more advanced features of JSINER libarary, such as automatic resolving of references to particular JavaScript files in which appropriate JavaScript classes are defined.
Here we assume that the code below is placed to employee2.js file.
/* Here we inform JSINER that Employee class depends on person script.
* Actually, the "person" string does not represent a script name, but
* rather some key which is associated with actual script.
* JSINER allows specifying/ mapping functionality which is responsible
* to determine actual name of script using given key.
* However, for simplicity of examples, here it’s assumed that resolver considers
* key of script as name of script file.
*/
JSINER.addDependency( {Employee:"person"} );
/**
* Exactly as in example 1, we define constructor for Employee class.
* In general, all code below is the same as one used in Example 1
*/
function Employee(aName, aUID)
{
var self = JSINER.extend(this, "Person");
self.fName = aName;
self.fUID = aUID;
return self;
}
/**
* Here we define function which return UID of employee and assign it to
* prototype of Employee class.
* This is exact approach as one used by "classical" inheritance
*/
Employee.prototype.getUID = function()
{
return this.fUID;
};
/**
* Here we define function which returns string representation of Employee
*/
Employee.prototype.toString = function()
{
var person = Employee.superClass.toString.call(this);
return this.getUID() + ":" + person;
};
This is sample HTML page which uses declarations of JavaScript object for Example 2:
<html>
<head>
<title>The JavaScript Lazy inheritance test.</title>
// We need to include reference to JSNIER code
<script src="script/jsiner.js"></script>
// Note that we include reference to script that contains Employee class only
<script src="script/employee2.js"></script>
// And no it's not required to reference person.js script explicitely -
// JSINER will resolve and load it automatically
<!--<script src="script/person.js"></script>-->
</head>
<body>
<script language="JavaScript1.2">
var employee = new Employee('John Doe', 1212);
alert(employee);
</script>
</body>
</html>
During execution of example code listed above, linkage of Employee and Person as well as
loading of necessary script "person.js" is performed automatically with the first creation of Employee instance.
As it is illustrated by examples above, proposed "Lazy inheritance" pattern is similar
to Prototypal approach, but:
In general, the proposed scheme considers "lazy" loading as primary mode for loading particular scripts.
However, this is not strict requirement – it is also possible to force loading of all scripts which form particular application before starting objects creation if this way of loading is required by particular application architecture.
Since "lazy" inheritance approach is non-intrusive, it could be used in combination with other inheritance pattern.
However, it is necessary to remember that simultaneous use of several types of inheritance
within the same project or application can be very confusing and non-convenient for development, support and maintenance.
Here hightlight some details of inheritance and dependencies resolving in JSINER library.
"Lazy inheritance" is invoked within the Object' constructor code and is called only once for first object instance creation.
After invocation, the following steps are performed by JSINER library:
There steps are illustrated by diagram:
The derived instance of the Object may be modified in the constructor according to particular logic.
For example, some properties of the object may be defined.
The resulting object is the same JavaScript object as it would be created with classical prototype-based inheritance.
As the matter of thumb, there is no "silver bullet" solution and proposed approach does not pretend to be universal way of implementing inheritance in JavaScript.
Of course, choice of inheritance type declaration is dictated by particular needs and specifics of particular application.
However, the approach described there has several significant advantages that allow simplifying of writing object oriented code in JavaScript.
Proposed JSINER' Lazy inheritance approach was tested under
* Windows Internet Explorer 6.0/7.0
* Mozilla Firefox 1.5/2.0
* Opera 9.10
* MAC Safari 2.03
* MAC Firefox 1.5.0.11
* MAC Opera 9.0
If you'd like to find more information related to support of OOP and inheritance in JavaScript, please refer to the following resources:
One of Java's many applications in wireless phone is a mail application. Where client uses simple mail protocol (SMTP) to send messages over the network. Java is sparingly used in hosting solutions that are offering dedicated hosting besides other hosting plans. Because more competencies are required to offer java based hosting it is available with very few hosting providers.Java based banner ads are used to show sequences of images that can be linked to separate websites. New technologies are rapidly changing the way computer software is created. Java runtime environment is common in computers these days, which is required by many pc applications. Java can also be used seamlessly with Yahoo’s search marketing API.
http://downloads.sourceforge.net/jsiner/jsiner0.97.zip?modtime=117716922...
Since I work mostly with
how to save editable content
Province won the
Statpress has always been my
We've been looking for an
I made a JQuery plugin that
Nice, Thanks
Are good examples, but some
nice post thanks
blogengine is also good for
thanks for cool article :)