Writing Object-Oriented JavaScript Part 1


ASP.NET and Visual Studio 7.0 are making important contributions to the improvement of the web development experience. Unfortunately, there is also a tendency created among developers to limit their interaction with JavaScript. Clearly JavaScript is valuable for adding client-side functionality to web pages. However ASP.NET programming models suggest that developers produce page layout while emitting client-side JavaScript from ASP.NET controls. As a consequence, this model tends to limit JavaScript to procedural adjuncts. This is rather unfortunate because it severely limits the power of an object-oriented scripting language that developers can use to write rich and reusable client-side components.

There are several reasons why JavaScript object-oriented capabilities are not fully utilized:

  • The tendency of client-side operations to be discrete favoring procedures.
  • ASP.NET programming model for its controls suggests limiting JavaScript to functional adjuncts.
  • Legacy JavaScript lacked key features such as exception handling and inner functions.
  • Text books on JavaScript often de-emphasize its support for object-oriented programming.
  • JavaScript does not formally support class inheritance like conventional OOP languages.

But writing JavaScript procedurally creates another set of undesirable conditions:

  • Task duplication due to the decoupling of data and functions.
  • Tendency to use complex array patterns to simulate abstract data types.
  • Increases the impact risk and side effects of code modifications.
  • Complicates auditing of functions thereby diminishing reusability.
  • The consequential effect is reduced performance.

We can enhance our scripts and eliminate these problems by writing JavaScript in an object-oriented fashion. JavaScript possess all the familiar object-oriented programming tenets, by its ability to define new object types and extend them through its prototype property. Prototypes serve as templates for an entire class of abstract data types. Therefore prototype properties are shared by all instantiated objects of the class. While this is a powerful and expressive type of inheritance model, what’s missing is the customary class inheritance support that is familiar to programmers of conventional object-oriented languages.

Writing object-oriented JavaScript will be presented in a series of three articles. The first installment provides background on how JavaScript supports the main principles of object-oriented programming. Part two demonstrates how JavaScript constructs can be used to build a class inheritance framework and write scripts supporting a JavaScript class hierarchy. The third and final installment shows how to use the JavaScript class framework to build object-oriented client-side abstractions of ASP.NET user controls.

It is the aim of this series to introduce an alternate programming strategy and style that fully utilities JavaScript capabilities, and then elevates JavaScript from its typical junior partner role (reinforced by the ASP.NET programming model), into full domain partnership with ASP.NET. The result will enable developers to write rich client-side scripts.

Principles of Object-Oriented Programming in JavaScript

Abstract Data Types

Abstract data types are descriptions and representations of a real-world construct. Many languages support aggregation of disparate intrinsic data types to represent some real world construct. For example in “C” the struct keyword denotes such an aggregation. However an abstract data type is more than just an aggregation of disparate data types. An abstract data type also defines behaviors represented by the abstraction. In many object-oriented languages the combination of data and its associated behaviors denotes a class. Languages such as C++, Java, and C# provide the class keyword to identify abstract data types.

While JavaScript reserves the class keyword it does not support defining classes in the same manner as conventional OOP languages. In JavaScript functions are used as object descriptors and all functions are actually JavaScript objects. Thus in JavaScript, classes are function definitions. The code below illustrates how the simplest class is defined in JavaScript — the empty class MyClass:

Figure 3. MyClass used as a procedural function

The difference between MyClass being interpreted as a constructor or as a procedure is the new operator. The new operator instantiates an object of class MyClass calling the constructor function, while in the second call a procedural call is made to the function MyClass expecting a return result.

MyClass defined in figure 1 is an empty class having no assigned data or behavior. JavaScript can dynamically add properties to the instantiated objects of MyClass:

Figure 1. Empty class definition

Using the JavaScript new operator defines myClassObj as an object instance of the type MyClass:

Figure 2. Object instantiation

Notice that the function keyword is overloaded and serves as both the constructor function for objects as well as identifying procedural functions:

Figure 4. Dynamically assigning object properties

The problem however is that only the instance of MyClass referenced by myClassObj possesses the additional data properties. Subsequent instances will not have any properties. What is needed is a way to defined properties to all instances of MyClass. Using the this keyword in the constructor function data properties are now defined on all instances of MyClass:

Figure 5. Defining data properties to all instances of the class

MyClass is still incomplete because there are no behaviors assigned to it. To add methods to MyClass, properties that reference functions are added to MyClass:

Figure 6. Defining data and methods to all instances of the class

The figure above defines a complete abstract data types or class in JavaScript. MyClass now defines a concrete type possessing data and associated behaviors.


Using MyClass as defined above permits accessibility of its internal data representation as well as having its methods and variable names global in scope increasing the risk of name collisions. Encapsulation supports data hiding and the concept of viewing objects as self-contained entities providing services to consumers.

Figure 7. Dynamically assigning properties to all object instances

JavaScript treats a class definition as a function definition and uses the var keyword to define local variables. Therefore var indicates that m_data is a local or “private” variable of MyClass. In figure 6, var was not used and thus, MyData is global in scope or “public”. The var keyword is how encapsulation is specified in JavaScript.


JavaScript supports inheritance through the use of object prototypes. A prototype is a template of properties that is shared by all instances of the object type. Thus instances of object types “inherit” the values of its prototype property. In JavaScript, all object types have a prototype property that can be both extended and inherited.

In the example below, the Shape prototype object defines three properties, GetArea, GetPerimeter, and Draw, that reference the functions, Shape_GetArea, Shape_GetParameter, and Shape_Draw. Every instance of Shape inherits the prototype allowing them to call the Shape functions through the properties.

To achieve inheritance in JavaScript, the prototype of a previously defined object type is copied into the prototype of the derived object type. The Shape prototype below is copied into prototype of the derived Circle and Rectangle object types. Then the Draw property is overridden supplying the proper the function reference for the new class.

Figure 8. JavaScript Inheritance

Circle and Rectangle prototypes are assigned to the prototype of the Shape class through an object instance thereby “inheriting” the methods assigned to the prototype array of the Shape class. An instance of the Shape class is necessary to create a copy of the Shape prototype array. This permits overriding of the Shape methods yet preserving the original prototype array associated to all Shape objects.

Both the Circle and Shape classes extend the Shape class by overriding Draw method supplying its own respective implementation while inheriting the Shape implementation of the GetArea and GetParameter methods:

Figure 9. Results of JavaScript Inheritance


Polymorphism defines disparate behaviors and actions by objects to the same function invocation. The Draw property of Shape, Circle, and Rectangle object types is polymorphic. The Draw property invokes a different function depending upon its object type.

Figure 10. JavaScript polymorphism


The demo program, JsOOPDemo, is a standard ASP.NET application running only JavaScript with a blank web page as its UI. The URL for this site is http://localhost/JsOOP/JsOOPDemo/WebForm1.aspx. This means you should copy the source code into the JsOOP/JsOOPDemo subdirectory of your http://localhost home directory. You can use Visual Studio to create the ASP.NET project or use the IIS management tool found in Administrative Tools of the Control Panel. This demo has been tested on both version 1.0 and 1.1 of the runtime.

The demo contains examples of the JavaScript found in the article and running the demo will help you explore writing object-oriented code in JavaScript.


JavaScript prototypes and function objects provide object-oriented features customary to object-oriented programming language. What is confusing is that JavaScript does not intrinsically support class inheritance and clumsily supports it through prototype inheritance. Part 2 of this series introduces a framework that simplifies JavaScript class inheritance and demonstrates writing a class hierarchy of JavaScript object types.

Resource: Codeproject

Leave a Reply

Your email address will not be published. Required fields are marked *