Principles of Writing Consistent, Idiomatic JavaScript.
UPDATE: For a more recent and comprehensive guide, see the Airbnb JavaScript Style Guide.
/*
Principles of Writing Consistent, Idiomatic JavaScript
Complete article and examples is here:
- https://github.com/rwldrn/idiomatic.js
*/
// Conditional Evaluation
// 4.1.1
// When only evaluating that an array has length,
// instead of this:
if ( array.length > 0 ) ...
// ...evaluate truthiness, like this:
if ( array.length ) ...
// 4.1.2
// When only evaluating that an array is empty,
// instead of this:
if ( array.length === 0 ) ...
// ...evaluate truthiness, like this:
if ( !array.length ) ...
// 4.1.3
// When only evaluating that a string is not empty,
// instead of this:
if ( string !== "" ) ...
// ...evaluate truthiness, like this:
if ( string ) ...
// 4.1.4
// When only evaluating that a string _is_ empty,
// instead of this:
if ( string === "" ) ...
// ...evaluate falsy-ness, like this:
if ( !string ) ...
// 4.1.5
// When only evaluating that a reference is true,
// instead of this:
if ( foo === true ) ...
// ...evaluate like you mean it, take advantage of built in capabilities:
if ( foo ) ...
// 4.1.6
// When evaluating that a reference is false,
// instead of this:
if ( foo === false ) ...
// ...use negation to coerce a true evaluation
if ( !foo ) ...
// ...Be careful, this will also match: 0, "", null, undefined, NaN
// If you _MUST_ test for a boolean false, then use
if ( foo === false ) ...
// 4.1.7
// When only evaluating a ref that might be null or undefined, but NOT false, "" or 0,
// instead of this:
if ( foo === null || foo === undefined ) ...
// ...take advantage of == type coercion, like this:
if ( foo == null ) ...
// Remember, using == will match a `null` to BOTH `null` and `undefined`
// but not `false`, "" or 0
null == undefined
// 5.1.1
// A Practical Module
(function( global ) {
var Module = (function() {
var data = "secret";
return {
// This is some boolean property
bool: true,
// Some string value
string: "a string",
// An array property
array: [ 1, 2, 3, 4 ],
// An object property
object: {
lang: "en-Us"
},
getData: function() {
// get the current value of `data`
return data;
},
setData: function( value ) {
// set the value of `data` and return it
return ( data = value );
}
};
})();
// Other things might happen here
// expose our module to the global object
global.Module = Module;
})( this );
// 5.2.1
// A Practical Constructor
(function( global ) {
function Ctor( foo ) {
this.foo = foo;
return this;
}
Ctor.prototype.getFoo = function() {
return this.foo;
};
Ctor.prototype.setFoo = function( val ) {
return ( this.foo = val );
};
// To call constructor's without `new`, you might do this:
var ctor = function( foo ) {
return new Ctor( foo );
};
// expose our constructor to the global object
global.ctor = ctor;
})( this );
// Naming
// A. You are not a human code compiler/compressor, so don't try to be one.
// The following code is an example of egregious naming:
// 6.A.1.1
// Example of code with poor names
function q(s) {
return document.querySelectorAll(s);
}
var i,a=[],els=q("#foo");
for(i=0;i<els.length;i++){a.push(els[i]);}
// Without a doubt, you've written code like this - hopefully that ends today.
// Here's the same piece of logic, but with kinder, more thoughtful naming
// (and a readable structure):
// 6.A.2.1
// Example of code with improved names
function query( selector ) {
return document.querySelectorAll( selector );
}
var idx = 0,
elements = [],
matches = query("#foo"),
length = matches.length;
for ( ; idx < length; idx++ ) {
elements.push( matches[ idx ] );
}
// A few additional naming pointers:
// 6.A.3.1
// Naming strings
// `dog` is a string
// 6.A.3.2
// Naming arrays
// `dogs` is an array of `dog` strings
// 6.A.3.3
// Naming functions, objects, instances, etc
// camelCase; function and var declarations
// 6.A.3.4
// Naming constructors, prototypes, etc.
// PascalCase; constructor function
// 6.A.3.5
// Naming regular expressions
rDesc = //;
// 6.A.3.6
// From the Google Closure Library Style Guide
functionNamesLikeThis;
variableNamesLikeThis;
ConstructorNamesLikeThis;
EnumNamesLikeThis;
methodNamesLikeThis;
SYMBOLIC_CONSTANTS_LIKE_THIS;