Maintaining sanity in Javascript

Tags:

Javascript allows a lot of things, a lot of them very, very bad things. Additionally, it offers many good ways to achieve the same goals. I have found that the only way to stay sane in this crazy Javascript world, is to set your own rules, and stick to them. The following is a set of rules that I have come up with, that I believe encourages structured and readable code.

Using quotes In C/C++ tradition, use double quotes ("") for strings, and single quotes ('') for characters. If a string contains other strings(such as xml elements), use double quotes for the "outside" quotes, singe quotes for the "inside" quotes.

Class declaration Always capitalize class names. Declare all class members inside the constructor closure. While it is allowed to add properties to a class after its initial declaration, I find it often does more harm than good to the legibility of the code. There is no need to ever touch the prototype object if you declare all members in the constructor.

"use strict"; Strict can only improve things, but it may break things if set globally(google it if you don't believe me) Always start a class declaration with "use strict";

Inheritance By calling "apply(this)" on another class constructor, it will execute that constructor using "this" as its context. Since our classes are fully contained in their constructor, it means that any public methods declared in that constructor will be reattached to the current constructor. It is important to realize that only public methods and variables will be available directly to the inheriting class, private variables and functions are still its own, and if we need access to those we'll need getters/setters. This is pretty much in line with C++ tradition, except that there is no such thing as a "protected" variable. We can make due without those. Occasionally, we'll want to add custom functionality by overwriting an inherited method. If we still want to use the parent method, we'll need to save it for later use. It is convenient to consistently use the same prefix. I like the dollar sign for this($). In order to preserve the parent method without making it publicly accessible, use the .bind method of the Function object. Example:

var $publicParent = this.publicParent.bind(this);

Note: if you simply assign this.publicParent to var $publicParent, the function will have an identity crisis when called, and won't be able to access any of the other class members. We can now re-declare a this.publicParent which, if we want it to, can call $publicParent in turn.

Private variables and methods All private variables and methods should be declared as high as possible in the constructor. Most established coding rules agree that it should be the very first thing after "use strict", though if you are inheriting methods from another class, that should be done first in order to give private methods access to inherited methods and variables. "var" statements can and should be chained, effectively turning your entire "private" block into a single "var" statement. The entire class declaration should not need any other "var" statements, even for iterators. Declare variables first, methods after. It is usually a good idea to declare "self" as a private variable and assign "this" to it. This is because the value of "this" can change unexpectedly depending on context, and depending on it may cause strange bugs, especially when depending on event listeners.

Public variables and methods All public variables and methods are parented to "this". They have access to any variable or function declared in the private "var" block inside the same class, but not that of an inherited class.

Do's and don't's Do not use the "function" statement to declare private methods. It is legal, it is possible, but it is inconsistent and confusing. In other words, use var myfunc = function () {} instead of function myfunc () {}

If the class you inherit from takes mandatory arguments to its constructor, pass them to the "apply" method as an array in the second argument.

Be consistent in the use of whitespace. Use either tabs or spaces to indent, but do so the same way everywhere.

The opening bracket for a block of code should be on the same line as the statement that opens it.

Be consistent in what type you assign to a variable. While it is legal in Javascript to assign a string to a variable that previously held an integer, it is a bad idea for obvious reasons. If you wish you can add variable types to your variable naming convention, for example: sVar for strings, nVar for numbers, bVar for booleans. I personally prefer not to, but it seems to be a fairly common practice.

Write comments. Use // to write a short (one line) description of what the code below it is intended to do, or write multiline /* */ comments for documentation purposes, preferably following the jsDoc standard(http://code.google.com/p/jsdoc-toolkit/w/list).

Always use correct grammar, capitalization and punctuation in comments. You never know who ends up reading it. Feel free to be funny, but not too funny. Try not to vent frustration in comments, use twitter for that instead.

The following example will return "60" when run in node.js: