Skip to content

Latest commit

 

History

History
executable file
·
671 lines (484 loc) · 13.1 KB

File metadata and controls

executable file
·
671 lines (484 loc) · 13.1 KB

Coding Conventions

JavaScript

Language

Semicolon

  • Always end statements with ;
// Right
console.log('even when not required');

// Wrong
console.log('even when not required')

Variable declarations

  • Declare on first use, not at top of function
  • Do not chain declarations unless inside for parentheses (repeat var for each variable in a separate statement)
  • Give descriptive names
    • Do not use similar names or synonyms for different variables unless following a convention
    • for...in iterators should use descriptive names
    • for iterators should use single character names
    • Use combination of plural for array and singular for each item in the array
  • Use camelCase, never underscores
  • Avoid using numbered variables (e.g. i1, i2, i3)

Scope

  • No implicit or single statement scopes
  • All scopes must be wrapped in {}
// Right

if (condition) {
    return;
}

// Wrong

if (condition) return;

if (condition)
    return;      

For loops

  • Iterator variable should be declared inside the for parentheses, unless already defined
  • Use for with arrays, for...in for objects (and always check hasOwnProperty())
  • When iterating over a fixed or calculated size, assign size to a variable inside the for declaration and use iterator variable name with l suffix
  • Always ++i, never i++
// Right

var name = 'john';

for (var i = 0, il = name.length; i < il; ++i) {
    console.log(name[i]);
}

// Wrong

var position;
var name = 'john' ;

for (position = 0; position < name.length; position++) {
    console.log(name[position]) ;
}

Prototype members

  • Prefix private members with _
Example.prototype.method = function () {

    this.public = 'external';
    this._private = 'internal';
};
  • Define self for passing this into nested functions
Example.prototype.method = function () {

    var self = this;
    
    call(123, function (err) {
    
        self.display(err);
    });
};

Function declaration

  • Declare functions via assignment
// Right

var method = function () {

};

// Wrong

function method() {

}

Enforcing new on Constructor

  • Use this.constructor === to check if a constructor function was called with new
// Right
Utils.assert(this.constructor === Server, 'Server must be instantiated using new');

// Wrong
Utils.assert(this instanceof Server, 'Server must be instantiated using new');

Style

Whitespace

  • Always spaces, never tabs
  • 4 spaces indents
  • No trailing whitespace at end-of-line
// Right

if (test) {
      if (value === 12) {
        console.log('result');
    }
}

// Wrong

if (test) {
  if (value === 12) {
    console.log('result');
  }
}

String literals

  • Always ' never "
// Right
var string = 'text in single quotes';

// Wrong
var string = "text in single quotes";

Newlines

  • Two empty lines between module functions or assignments (end of function to comment about next function)
exports.get = function () {

    // Some code
};  
                                                            // 1    
                                                            // 2
/**
 * jsDoc comment
 */
internals.utility = function () {

    //Some code
};
  • Newline after { except for inlined or empty objects
    • Inline an object when it improves readability and unlikely to change often
    • No inline object in assignment unless empty
// Right

if (condition) {
    execute(value, { strict: true });
}

if (condition) {
    var options = {
        strict: true
    };
    execute(value, options);
}

var empty = {};

// Wrong

if (condition) { execute(value, { strict: true }); }

if (condition) {
    var options = { strict: true };
    execute(value, options);
}

var empty = {
};
  • Newline after }
    • Only exception is when followed by ,, ;, ); which must be followed by a newline
    • Includes before else, catch, etc.
    • Empty line after } if not last statement in scope
// Right

if (condition) {  
    value = {
        func: function () {
        
            cosole.log('example');
        },
        message: 'hello'
    };
    
    execute(value, function (err) {
    
        console.log(err);
    });
}
else {
    console.log('otherwise');
}

// Wrong

if (condition) {  
    value = {
        func: function () {
        
            console.log('example');
        }, message: 'hello'
    };
    execute(value, function (err) {
    
        console.log(err); }
    ); 
} else {
    console.log('otherwise');
}
  • Empty line after {
    • Following a multi-line condition
    • In function scope declarations
// Right

exports.method = function () {

    if (condition) {  
        if (otherCondition) {
            console.log('sometimes');
        }

        if (result &&
            result.code === 200) {
        
            console.log('special case');
        }
    
        console.log('always');
    }
    
    execute(123, function (err) {
    
        console.log(err);
    });
    
    var empty = {};
};

// Wrong

exports.method = function () {
      if (condition) {
      
        if (otherCondition) {
    
            console.log('sometimes');
        }
 
        if (result &&
            result.code === 200) {
            console.log('special case');
        }
   
        console.log('always');
    }
      
    execute(123, function (err) {
        console.log(err);
    });

    var empty = {
    };
};
  • No empty line before end of scope
// Right

if (condition) {
    if (otherCondition) {
        console.log('done');
    }
}

// Wrong

if (condition) {  
    if (otherCondition) {
        console.log('done');
        
    }
    
}

Spaces

  • Use one and only one space (when required)
// Right
var value = calculate(1, 3);

// Wrong
var  value =  calculate(1,  3);
  • No space between function name and (
// Right

function example() {

    return value;
}

var key = example();

// Wrong

function example () {

    return value;
}

var key = example ();
  • No space after ( or before )
// Right

execute('order', 34);

if (result === 'ok') {
   console.log('success');
}

// Wrong

execute( 'order', 34 );

if ( result === 'ok' ) {
   console.log( 'success' );
}
  • No space before object key :, always after object key :
// Right

var obj = {
    a: 1,
    b: 2,
    c: 3
};

// Wrong

var obj = {  
    a : 1,
    b :2,
    c:3
};
  • No space before ;, always after ; if not end-of-line
// Right

var name = 'john';

for (var i = 0, il = name.length; i < il; ++i) {
    console.log(name[i]);
}

// Wrong

var name = 'john' ;

for (var i = 0, il = name.length;i < il ;++i) {
    console.log(name[i]) ;
}
  • Always space after reserved keywords (if, else, for, return, function, etc.)
// Right

for (var book in books) {  
    if (books.hasOwnProperty(book)) {
        console.log(book.name);
    }
}

// Wrong

for(var book in books) {  
    if(books.hasOwnProperty(book)) {
        console.log(book.name);
    }
}
  • Always space after { and before } in inlined object
    • No space for empty objects {}
    • One space for empty functions { }
// Right

var user = { name: 'john', email: 'john@example.com' };
var empty = {};
var callback = function () { };

// Wrong

var user = {name: 'john', email: 'john@example.com'};
var empty = {  };
var callback = function () {};
  • No space after [ and before ] in inlined arrays
// Right
var numbers = [1, 2, 3];

// Wrong
var numbers = [ 1, 2, 3 ];
  • Always space after //
// Right
// Some comment

// Wrong
//Some comment
  • No space before ,, always after , unless end-of-line
// Right

var numbers = [1, 2, 3];
var user = { name: 'john', email: 'john@example.com' };

for (var i = 0, il = name.length; i < il; ++i) {
    console.log(name[i]);
}

// Wrong

var numbers = [1,2 ,3];
var user = { name: 'john',email: 'john@example.com' };

for (var i = 0,il = name.length; i < il; ++i) {
    console.log(name[i]);
}
  • Always space before and after operators, unless following ident or end-of-line
// Right

var a = 1 + 3;
var b = 'john' +
        ' ' +
        'doe';

// Wrong

var a=1+3;
var b='john'+
      ' '+
      'doe';

Commas

  • Never begin a line with , (always at the end of the previous line)
// Right
execute('some error message',
        12345,
        this);

// Wrong
execute('some error message'
        ,12345
        ,this);

Operators

  • Never begin a line with an operator (always at the end of the previous line)
// Right

var message = 'Hello ' +
              'Steve, ' +
              'How are you?';

if (value === 'hello' &&
    result === 'ok') {
    
    console.log('yes');
}

// Wrong

var message = 'Hello '
              + 'Steve, '
              + 'How are you?';

if (value === 'hello'
    && result === 'ok') {
    
    console.log('yes');
}

Comments

  • Always use // unless it's a jsDoc declaration or license header

  • Always begin sentences with an upper case

  • No trailing . unless comment contains multiple sentences

  • Formal style, consistent voice, no humor, present tense

  • No developer name or other personal notes

  • No TODOs

  • Line

    • Provides narrative for the following single code line (or single statement broken for readability)
    • One line of comment only
    • One empty line before and none after the comment line
    • No empty line before when following { unless other rules require it
function execute() {

    // Initialize state
    var position = 0;
    
    if (condition) {
        // Return message
        return 'hello';
    }
}
  • Segment
    • Provides narrative for the following code section (one or more lines of code, with or without line breaks)
    • One or more lines of comments
    • One empty line before and one after comments block
function execute() {

    // Print each book's name
    
    for (var book in books) {
    
        // Check for valid properties
        
        if (books.hasOwnProperty(book)) {
            console.log(book.name);
        }
    }
}
  • Note
    • Explains the behaviour of a single code statement (can be broken into multiple lines)
    • Used to document unexpected behaviour or non-standard practice
    • Appears immediately at the end of the line (or statement) it describes, following whitespace to separate it from code block
function execute(value) {

    if (value !== null &&
        value !== undefined) {      // Explicit check as 'value' can be 0
        
        console.log(value);
    }
}

Multi-line statements

  • Statements should only be broken into multiple lines to improve readability

  • Break statements if they are longer than 150 characters long

  • No empty lines in the middle of a single statement

  • Indent multi-line statements

  • Conditions should be indented to the first character of the condition in the first line

if (result &&
    result.status &&
    result.status.code === 200) {

    console.log('success');
}
  • Variable should be indented to the first character of the value in the first line
var message = "hello" +
              " and welcome";

Node

Require

  • Use uppercase variable names for imported modules
  • All require statements must be declared at the top of the module
  • Always use relative paths

Module globals

  • Every module can only have two top level globals:
    • exports - defined automatically by node
    • internals - must be declared as an object at the top of each module immediate following the require section
  • Any variable global to the module must be a property of internals, including constants
  • If a module has automatically executing code, it must be contained within a function (using the internals namespace) and called at the top of the module after the internals declaration