JS Style Guide - TwoGears/hakomo-guides GitHub Wiki

Table Of Contents

  1. Arrays
  2. Objects
  3. Variables
  4. Conditional Expressions
  5. Strings
  6. Blocks
  7. Functions
  8. Properties
  9. Whitespace
  10. Commas
  11. Naming Conventions
  12. Comments

Arrays

  • Use the literal syntax for array creation

     // bad
     var numbers = new Array();
    
     // good
     var numbers = [];
  • Copy Array

     // wrong
     const newArray = arr;
     // Both variables point to 1 single array in memory.
    
     // good
     const newArray = [...arr];
    
     // old good
     const newArray = arr.slice();
  • Merge Arrays

     // bad
     
    
     // good
     var array3 = array1.concat(array2);
    
     // good es6
     const array3 = [...array1, ...array2];
  • Iterate over arrays

     // bad
     let a = ["a", "b", "c"];
     for (key in a) {
       console.log(a[key]);
     }
     // Explained: https://stackoverflow.com/questions/9329446/for-each-over-an-array-in-javascript/9329476#9329476
    
     // good
     const arrwobj = [{a:1}, {b:2}];
     for (const val of arrwobj) { 
     	console.log(val);
     }
    
     // good old way
     let a = ["a", "b", "c"];
     for (let index = 0; index < a.length; ++index) { // keep index local to the forloop please
     	console.log(index, a[index]);
     }
    
     // good another way
     var a = ["a", "b", "c"];
     a.forEach(entry => (
     	console.log(entry);
     ));
  • When you need to copy an array use .slice()

     var len = items.length,
         itemsCopy = [],
         i;
    
     // bad
     for (i = 0; i < len; i++) {
       itemsCopy[i] = items[i];
     }
    
     // good
     itemsCopy = items.slice();
  • Sort array by object property

     function compare( a, b ) {
       if ( a.last_nom < b.last_nom ){
         return -1;
       }
       if ( a.last_nom > b.last_nom ){
         return 1;
       }
       return 0;
     }
    
     objs.sort( compare );

Back to top

Objects

  • Use the literal syntax for object creation

     // bad
     var item = new Object();
    
     // good
     var item = {};
  • Don't use reserved words as keys

  • Check if value is Object

         Object.prototype.toString.call(possibleObject) === '[object Object]';
  • Check if Object has Key

     // bad (explanation: https://eslint.org/docs/rules/no-prototype-builtins)
     obj.hasOwnProperty('key')
    
     // good
     Object.prototype.hasOwnProperty.call(obj,'key')
  • Objects: Iterate

     // bad
     
     // good simplest
     Object.keys(obj).forEach(key => {
     	console.log(key + ': ' + obj[key]);
     });
    
     // good relatively fast, but more writing
     for (const key in obj) {
     	console.log(key + ': ' + obj[key]);
    
     	//optional check for properties from prototype chain
     	if (obj.hasOwnProperty(key)) {
     		//no a property from prototype chain     
     	}else{
     		//property from protytpe chain
     	}
     };
  • Keys: Filter

     // bad
     
     // good
     const filteredArray = Object.keys(obj).filter(key => (
     	someArray.indexOf(key) // Your condition
     ));

Back to top

Variables

  • Always use var to declare variables. Not doing so will result in global variables polluting the global namespace.

     // bad
     pesho = new Pesho();
    
     // good
     var pesho = new Pesho();
  • Use var for every declared variable.

     // bad
     var pesho = 'gosho',
     	alienNinja = 'awesome!',
     	setHumorTo = '10%';
    
     // good
     var pesho = 'gosho';
     var	alienNinja = 'awesome!';
     var	setHumorTo = '100%';
  • Declare unassigned variables last.

     // bad
     var i, j, length;
     var pesho = 'gosho';
    
     // good
     var pesho = 'gosho';
     var length;
     var	i;
     var	j;
  • Always assign variables at the top of their scope.

     // bad
     function() {
     	doSomethingBeforeVar();
    
     	if (condition) {
     		doAnotherThing()
     	}
    
     	var theVariable = 9999999;
    
     	return 'pesho';
     }
    
     // good
     function() {
     	var theVariable = 9999999;
    
     	doSomethingBeforeVar();
    
     	if (condition) {
     		doAnotherThing()
     	}
    
     	return 'pesho';
     }

Back to top

Conditionals

  • Use === and !== over == and !=.

  • Conditional expressions are evaluated using coercion and always follow these rules:

    • Objects evaluate to true
    • Undefined evaluates to false
    • Null evaluates to false
    • Booleans evaluate to the value of the boolean
    • Numbers evaluate to false if +0, -0 or NaN, otherwise true
    • Strings evaluate to false if an empty string '', otherwise true
     if ([0]) {
     	// true
     	// because an array is an object and objects evaluate to true
     }
  • Use shortcuts

    // bad
    if (name !== '') {
      // ...stuff...
    }
    
    // good
    if (name) {
      // ...stuff...
    }
    
    // bad
    if (collection.length > 0) {
      // ...stuff...
    }
    
    // good
    if (collection.length) {
      // ...stuff...
    }

Back to top

Strings

  • Use single quotes '' for strings
     // bad
     var name = "Unufri Stavrev";
    
     // good
     var name = 'Unufri Stavrev';
    
     // bad
     var fullName = "Dick " + this.lastName;
    
     // good
     var fullName = 'Dick ' + this.lastName;
  • Strings longer than 80 characters should be written across multiple lines using string concatenation
     // bad
     var errorMessage = 'This is a super long error that was thrown because of Batman. When you stop to think about how Batman had anything to do with this, you would get nowhere fast.';
    
     // bad
     var errorMessage = 'This is a super long error that was thrown because \
     of Batman. When you stop to think about how Batman had anything to do \
     with this, you would get nowhere \
     fast.';
    
     // good
     var errorMessage = 'This is a super long error that was thrown because ' +
       'of Batman. When you stop to think about how Batman had anything to do ' +
       'with this, you would get nowhere fast.';

Back to top

Blocks

  • Use braces with all multi-line blocks
     // bad
     if (test)
         return false;
    
     // good
     if (test) return false;
    
     // good
     if (test) {
         return false;
     }
    
     // bad
     function() { return false; }
    
     // good
     function() {
         return false;
     }

Back to top

Functions

  • Function expressions
     // anonymous function expression
     var anonymous = function() {
     	return true;
     };
    
     // named function expression
     var named = function named() {
     	return true;
     }
    
     // immediately-invoked function expression (IIFE)
     (function() {
     	// do awesome stuff here
     })();
  • Function declaration
     function awesomeFunction() {
     	return true;
     }
  • Never declare a function in a non-function block (if, while, etc).
  • Never name a parameter arguments, this will take over the arguments object that is givent to every function scope
     // bad
     function nope(name, options, arguments) {
       // ...stuff...
     }
    
     // good
     function yup(name, options, args) {
       // ...stuff...
     }

Back to top

###Properties

  • Use dot notation when accessing properties
     var luke = {
       jedi: true,
       age: 28
     };
    
     // bad
     var isJedi = luke['jedi'];
    
     // good
     var isJedi = luke.jedi;
    
     /*
     	an exception is when the key you want
     	to access has a hyphen separating the
     	the words that form it
     */
    
     var luke = {
     	is-jedi: true
     };
    
     var isJedi = luke['is-jedi'];

Back to top

Whitespace

  • Use soft tabs set to 4 spaces
     // bad
     function() {
     ..return false;
     }
    
     // worse
     function() {
     .return false;
     }
    
     // good
     function() {
     ....return false;
     }
  • Place 1 space before the leading brace
     // bad
     function test(){
       console.log('test');
     }
    
     // good
     function test() {
       console.log('test');
     }
    
     // bad
     dog.set('attr',{
       age: '1 year',
       breed: 'Bernese Mountain Dog'
     });
    
     // good
     dog.set('attr', {
       age: '1 year',
       breed: 'Bernese Mountain Dog'
     });
  • Set off operators with spaces
     // bad
     var x=y+5;
    
     // good
     var x = y + 5;
  • Use indentation when making long method chains
     // bad
     $('#items').find('.selected').highlight().end().find('.open').updateCount();
    
     // good
     $('#items')
     	.find('.selected')
     		.highlight()
     		.end()
         .find('.open')
         	.updateCount();

Back to top

Commas

  • Leading commas. Nope
     // bad
     var person = {
     	firstName: 'Unufri'
       , lastName: 'Stavrev'
       , age: 20
     }
    
     // good
     var person = {
     	firstName: 'Unufri',
     	lastName: 'Stavrev',
     	age: 20
     }

Back to top

Naming Conventions

  • Avoid single letter names. Be descriptive with your naming.
     // bad
     function q() {
       // ...stuff...
     }
    
     // good
     function query() {
       // ..stuff..
     }
  • Use camelCase when naming objects, functions, and instances
     // bad
     var MyObject = {};
     var my_other_object = {};
    
     var u = new user({});
    
     // good
     var thatsBetter = {};
     var thatToo = {};
    
     var user = new User({});
  • Use PascalCase when naming constructors or classes
     // bad
     function user(options) {
       this.name = options.name;
     }
    
     var bad = new user({
       name: 'nope'
     });
    
     // good
     function User(options) {
       this.name = options.name;
     }
    
     var good = new User({
       name: 'yup'
     });
  • Use a leading underscore _ when naming private properties
     // bad
     this.__firstName__ = 'Panda';
     this.firstName_ = 'Panda';
    
     // good
     this._firstName = 'Panda';

Back to top

Comments

  • Use /** ... */ for multiline comments. Include a description, specify types and values for all parameters and return values.
     /**
      * make() returns a new element
      * based on the passed in tag name
      *
      * @param <String> tag
      * @return <Element> element
      */
     function make(tag) {
    
       // ...stuff...
    
       return element;
     }
  • Use // for single line comments. Place single line comments on a newline above the subject of the comment. Put an empty line before the comment.
     // bad
     var notGood = true // don't do that
    
     // good
     // that's better
     var awesome = true

Back to top

⚠️ **GitHub.com Fallback** ⚠️