DHTML Javascript Coding Guidelines 2
DHTML Javascript Coding Guidelines 2
This document outlines best practices for developing code in DHTML/JavaScript. It’s meant
to be a living document that reflects our collective wisdom of what works and what doesn’t.
A best practice could exist for one or more of these reasons –
Style Guidelines
1. General
Tabs should be 4 characters wide
3. Naming conventions
4. Braces
The opening brace should be on the line following if, for, while, etc.
Always use an opening and closing brace
if(a > 4)
{
a++;
}
Architectural Best Practices
1. Declare your DOM elements
In DHTML, it’s possible to generate HTML elements dynamically using JavaScript. While this
is unavoidable in some situations; dynamic elements make your code harder to read, debug
and maintain. Whenever possible, declare your DOM elements in HTML.
.loginbutton
{
background-color:White;
}
.loginbutton:hover
{
background-color:Red;
}
function MyComponent(element)
{
...
This kind of circular reference can cause memory leaks if it’s not explicitly broken by the
application. One way to avoid this is to refer to the DOM object by id.
If you must create a circular reference in your application, make sure you break it explicitly
when you’re done using the referenced objects.
function MyComponent(element)
{
...
var i = 10;
element.onclick = function(e)
{
i++;
...
}
}
While closures are a convenient construct, their use can inadvertently cause circular
references between DOM objects and JavaScript objects.
For example, in the listing below, using a closure creates a circular reference through the
closure scope variable ‘panel’.
function MyComponent(element)
{
...
The circular reference above could be eliminated by explicitly setting ‘panel’ to null.
function MyComponent(element)
{
...
Another way to get rid of the circular reference is to avoid using the closure altogether
function MyComponent(element)
{
...
function myClickHandler()
{
...
}
JavaScript does not have a formal notion of classes. Nevertheless, JavaScript objects can
serve as classes using prototype based inheritance.
Class Definition
JavaScript classes are defined through their constructor functions. The template below
defines a constructor for ‘MyComponent’. The constructor accepts three arguments and
creates a div element to render its contents.
// Constructor
function MyComponent(arg1, arg2, arg3)
{
this._arg1 = arg1;
this._arg2 = arg2;
this._arg3 = arg3;
// Create a reference from the DOM element back to the object instance
element.myComponent = this;
Note - It’s important to avoid circular references between the JavaScript objects and DOM
elements. Circular references of this type can cause memory leaks. In the constructor
above, circular references are avoided by storing the DOM element by id (as opposed to
storing the actual element).
Defining Methods
Methods should be created on the prototype object for the class. The prototype object is
automatically created for every JavaScript object. All instances of a class share a prototype
object. This makes it a convenient and efficient vehicle for defining methods on the class.
Within the method, the ‘this’ keyword can be used to reference instance specific data.
MyComponent.prototype.setSize = function(w, h)
{
var element = document.getElementById(this.elementId);
element.style.width = w + "px";
element.style.height = h + "px";
this._width = w;
this._height = h;
}
Static Methods
In some instances, it may be necessary to define a static method on the class. For example,
event handlers on a DOM element will require a static method. Static methods are defined
directly on the class as in the example below. Note that the ‘this’ keyword is not accessible
within the static method. So we store the instance object as a property on the DOM
element.
MyComponent.onClick = function(e)
{
var ev = getEvent(e); // Browser independent function to get the event
var element = getEventSrc(ev); // Browser independent function
Instantiation
Pattern 2 - Singleton
The singleton pattern is used when a single instance of the component exists for the lifetime
of the application. Singletons are created using the same methodology as a regular
component. With two exceptions –
// Singleton constructor
MySingleton.CreateInstance = function()
{
if(MySingleton.instance == null)
{
MySingleton.instance = new MySingleton();
}
}
// Internal constructor
function MySingleton()
{
// Create an element
var element = document.createElement('div');
element.id = "mySingleton1";
this.elementId = element.id;
}
// Methods
MySingleton.setSize = function(w, h)
{
if(MySingleton.instance)
{
var element = document.getElementById(MySingleton.instance.elementId);
element.style.width = w + "px";
element.style.height = h + "px";
}
}