Skip to content

Instantly share code, notes, and snippets.

@Armen138
Created March 5, 2012 19:42
Show Gist options
  • Save Armen138/1980570 to your computer and use it in GitHub Desktop.
Save Armen138/1980570 to your computer and use it in GitHub Desktop.
Coding rules for Structured Javascript
/*
Structured Javascript
* 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.
Below follows an example class and a class that inherits from it. When run in node.js, it will output "60".
*/
var AClass = function () {
"use strict";
//Private variables and functions
var self = this,
priv1 = 66,
priv2 = 2,
privMethod = function () {
return priv2;
},
privMethod2 = function () {
return priv1;
};
//Public variables and functions
this.pub1 = 22;
this.pub2 = 33;
this.pubMethod = function (x) {
return privMethod() + this.pub1 + x;
};
this.pubMethod2 = function () {
return privMethod2 + this.pub2;
};
//Constructor body
if (priv1 < 44) {
priv1 += priv2;
}
};
var BClass = function () {
"use strict";
//Inherit from Aclass
AClass.apply(this);
//Private variables and functions
var self = this,
$pubMethod = this.pubMethod.bind(this),
priv1 = 33;
//Public variables and functions
this.pubMethod = function () {
return $pubMethod(3) + priv1;
};
};
var bClass = new BClass();
console.log(bClass.pubMethod());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment