Implementing "Real" Classes in JavaScript San Jose CA

JavaScript developers can use the presented compact implementation to take advantage of most of the features of the Java classes. This will enable the use of robust design patterns needed for AJAX and Rich Internet Applications (RIA).With the presented compact implementation. JavaScript developers can take advantage of most of the features of Java classes, thus enabling the use of robust design patterns needed for AJAX and RIA applications.

Local Companies

cccp
408-265-2902
2585 Westgate Ave
San Jose, CA
Accoladde
+91 9962299053
2033 Gateway place
San Jose, AK
Accoladde
+1 408 651 7050
2033 Gateway Place
San Jose, CA
Concierge for Business
408 993-1368
472 Clifton Avenue
San Jose, CA
VeriPIc
1-888-837-4742
2360 Walsh Ave
Santa Clara, CA
Zoniac, Inc.
619.448.7284
1649 S. Main Street, Ste. 105
Milpitas, CA
InsidersReferral.com, Inc.
(408) 338-6542
386 America Ave
Sunnyvale, CA
TrueSoft, Inc.
408-329-3011
440 N. Wolfe Rd.
Sunnyvale, CA
Accept Software Corporation
1.866.423.8376
42808 Christy Street, Suite 216
Fremont, CA
smartData Enterprises
646-367-8215
706 Colorado Avenue,
Palo Alto, CA 94303, CA

provided by: 
Originally published at Internet.com


Series Description

The AJAX from Scratch series of articles describes fundamental techniques needed to develop AJAX Rich Internet Applications in JavaScript from scratch. Each article focuses on a particular (usually little-covered) aspect of developing browser-side functionality without the use of commercial or server-based frameworks. The techniques described are illustrated in Gravey, a small, but real-world, JavaScript framework for AJAX and RIAs.

Abstract

With the increasingly popular AJAX and RIA paradigms, the impetus to build complicated dynamic user interfaces is driving developers to use the same design patterns (e.g. Model-View-Controller) formerly tied to "fat" GUI clients. All of these design patterns expect the consistency of class-based objects as provided in languages like C++ and Java. However, since JavaScript does not use classes, Rich Internet Applications must emulate their functionality. This article describes one such emulation technique and demonstrates why many commonly used techniques fall short.

In order to develop non-trivial logic in JavaScript, and especially when using standard design patterns, a platform is needed that provides for programming with classes. An implementation of such a platform is presented that is based on the techniques used in the Gravey framework. Presented is a very small set of JavaScript code and programming conventions that together emulate classical classes of the sort familiar to C++ and, in particular, Java programmers.

For those object-oriented developers whose experience with JavaScript has been shallow or not particularly object-oriented (e.g. the author a few years ago), it may not be obvious why such a platform is needed. It is only when understanding how JavaScript actually works, and why simplistic approaches to JavaScript "classes" fail, that it becomes apparent why the particulars of the presented platform are needed.

JavaScript doesn't already have Classes?!

Or, Prototype-based vs Class-based, Dynamic vs Static, Weakly-typed vs Strongly-typed

Just as a person, born and confined to an entirely blue room, has a hard time conceiving of green, the typical OO programmer has a hard time imagining objects and inheritance without classes. JavaScript is a language with objects and inheritance but no classes. For casual JavaScript programmers, this fact is often not even known because (a) JavaScript has syntax that is deceptively similar to Java, even though something completely different is going on semantically
(b) Many web development texts talk as if JavaScript has merely a slightly different syntax from Java, rather than describing how they are fundamentally different categories of languages.

JavaScript is generally a prototype-based language; where each object is not constructed from a predefined template of attributes and methods (i.e. a class), but is effectively just a dynamic associative array of attribute names and values. In other words, JavaScript allows each object's attributes to be dynamically created and deleted at runtime. It also (not being strongly-typed) allows the same attribute (or any variable for that matter) to be assigned values of different data types over time. And finally, an attribute value can be a Function object which can be invoked in a manner similar to a method. JavaScript has syntactic sugar; to make creating object instances, accessing their attributes, and invoking their "methods", look like Java syntax.

Regarding subclasses, Java's classical inheritance; defines one class as a subclass of another thus inheriting its methods and attributes. When a class instance (i.e. an object) is created, that object has all the attributes and methods of the class' entire inheritance hierarchy. With JavaScript's prototype inheritance, an object may point to another object as its "prototype". When reading an object attribute, if that attribute is not found, the object's prototype will be searched. Since that prototype object may, in turn, point to another prototype of its own, an entire inheritance chain may be built (ala a class hierarchy).

A big difference, however, is that prototypes, being simple objects, may be changed at runtime and hence dynamically change what is being inherited. On the other hand, if multiple prototype objects of the same "class" are created, changes to one prototype object will not be seen by those pointing to different prototype objects. Further more, when assigning a value to an inherited attribute, the prototype object is not changed. Instead, a new attribute with the same name is created on the top-level object, SO, implementing "class" (aka static) attributes via simple prototype objects doesn't really work.

Note that I described JavaScript as "generally prototype-based". This is because it has other features that look a lot like classes! JavaScript allows functions to be used as "class" constructors; and recognizes their names via the instanceof operator. JavaScript also has several predefined "classes" (e.g. Date, String, Function, etc.).

The GrvObject Approach

With the presented technique, it is a simple matter (as shown in Listing 1) to declare a class along with its superclass, constructor, and methods, as well as, to use "super".

Listing 1. Simple example using the GrvObject technique 1 Class(A); 2 function A() 3 { 4 this.konstructor = function( arg1 ){ this.bar = arg1; } 5 this.aMethod = function( ... ){ ... } 6 this.anotherOne = function( ... ){ ... } 7 } 8 9 Class(B).Extends(A); 10 function B() 11 { 12 this.konstructor = function( arg1, arg2, optionalArg3 ) 13 { 14 this.souper( arg2 ); //ie. invoke "A.konstructor" 15 this.foo = arg1; 16 } 17 18 this.aMethod = function(...){ this.souper(42); ... } 19 this.yetMore = function(...){ ... } 20 } 21 22 var x = new B(3,4,5);

Normal looking JavaScript "constructor" functions are defined in lines 2-7 and 10-20 except that any logic other than defining methods is contained in the special "konstructor" method.

The Platform Implementation

While the complete documented version of the platform. is contained in a few JavaScript include files, the compact, standalone code in Listing 3 implements the basic technique. Lines 12-18 implement the "super" capability. Lines 27-31 replace the original class function with a wrapper function that, in turn, uses the original class as its prototype. Instances of the wrapper class will hold all the instance variables and only the singleton prototype objects contain method definitions.

Listing 3. The GrvObject technique's basic implementation (grvObject.js) 1 Class(GrvObject); //special root class 2 function GrvObject(){ 3 this.souper = function() { 4 var superMethod = this.souper.caller.souper; 5 return (superMethod) ? superMethod.apply( this, arguments ) : null; 6 } 7 } 8 9 function grvExtends( superClass ){ //link super and sub classes 10 this.baseClass.prototype = (this==GrvObject) ? null : superClass.prototype; 11 this.prototype = new this.baseClass(); 12 if (this.baseClass.prototype) 13 for (var x in this.prototype) { // iterate over all properties 14 var m = this .prototype[x]; // the method 15 var s = this.baseClass.prototype[x]; // its super 16 if (s && (s!=m) && (m instanceof Function) && (s instanceof Function)) 17 m.souper = s; 18 } 19 } 20 21 function grvFuncName(f){ //extract name from function source 22 var s = f.toString().match(/function\s*(\S*)\s*\(/)[1]; 23 return s ? s : "anonymous"; 24 } 25 26 function Class( theClass ){ 27 var originalClass = theClass; 28 self[ grvFuncName(theClass) ] = theClass = function(){ 29 arguments.callee.prototype.konstructor.apply( this, arguments ); 30 } 31 theClass.baseClass = originalClass; 32 theClass.Extends = grvExtends;//so we can call Extends as a method 33 theClass.Extends(GrvObject);//required here even if overridden later 34 return theClass; 35 }

The utility function grvFuncName (lines 21-24) takes a function object and returns the function name (made possible because, in JavaScript, the function object contains the function source code).

Conclusion

With the presented compact implementation. JavaScript developers can take advantage of most of the features of Java classes, thus enabling the use of robust design patterns needed for AJAX and RIA applications. Use of this technique does not preclude mixing in other techniques or legacy code thus allowing the technique to be added to existing code.

Examples

The source code in this article is available for viewing or download at Polyglotinc.com or here at Developer.com.

About the Author

As principal consultant of PolyGlot, Inc., Bruce Wallace has provided consulting and custom computer software development services around the world. Projects have been completed in Sydney Australia, Perth West Australia, "Silicon Valley", "Route 128" MA, Austin TX, Atlanta GA, and Charlotte NC.

Copyright

© Copyright, 2006-2007, PolyGlot, Inc.

Author: Bruce Wallace

Read article at Internet.com site

Featured Local Company

cccp

408-265-2902
2585 Westgate Ave
San Jose, CA
http://cccptech.com

Related Local Events
MACWORLD 2010
Dates: 1/4/2010 - 1/8/2010
Location: Moscone Convention Center
San Francisco, CA
View Details

Informex USA
Dates: 2/16/2010 - 2/19/2010
Location: Moscone Convention Center, San Francisco
San Francisco, CA
View Details

Advanced Lithography
Dates: 2/21/2010 - 2/26/2010
Location: San Jose Convention Center
San Jose, CA
View Details

Contraceptive Technology Conference : San Francisco
Dates: 3/24/2010 - 3/27/2010
Location: Hyatt Regency Hotel
San Francisco, CA
View Details

Web 2.0 Summit
Dates: 10/20/2009 - 10/22/2009
Location: Westin San Francisco Market Street
San Francisco, CA
View Details