Writting Code

Naming things

Naming variables

Avoid short or incompreensible names for variables and functions


// BAD
var x1; // too short
var input1; // input for?
var tabUserActive; // the tab can be inactive?
            

Naming Functions

Avoid short or incompreensible names for variables and functions


// BAD: names that describes the code, not the fucntionality
function olderThan18(age){
  return age >= 18;
}
// GOOD: describe the rule
function isLegalAge(age){
  return age >= 18;
}
            

Naming in general

Create patterns for names

Examples:


// $ on start for jquery elements
var $header    = $('#header');
var $menuItens = $('#menu a');

// constants
var IMAGES_PATH = '/assets/images/';
var CLIENT_NAME = 'Fulan0';

// _ for private values
var _count = 0;

// use the variable linked to the value
var termsAccepted // true / false
var hasVoucher // true / false

// _ try to not mix snake_case and cameCase
var user_full_name = userFirstName + user_lasName;
            

Comments

Write comments to help other developers.

Avoid just copy comments to look good


// Bad
/*
*  @module user
*  @name get
*  @params id, number
*/
function get( id, name){}

// GOOD
// get user for given id on localstorage
function get( id, name){}
            

Dont mix technologies

Avoid use javascript to create styles or content.


// BAD
$('.user-name').css({
  'border'  : '1px solid red',
  'color'   : 'red'
});
// GOOD
$('.user-name.error').addClass('error');
            

Use short syntax

Learn about the short notations and use.


// BAD
var colors = new Array();
colors[0]='pink';
colors[1]='blue';
colors[2]='green';
// GOOD
var colors = ['pink', 'blue', 'green'];

// BAD
if(v){
   var x = v;
} else {
   var x = 10;
}
// GOOD
var x = v || 10;

// BAD
var direction;
if(x > 100){
   direction = 1;
} else {
   direction = -1;
}
// GOOD
var direction = (x > 100) ? 1 : -1;
            

Configuration

Program thinking with configurations


// BAD
$.ajax({
  type: "POST",
  url: "api/users",
  data: {limit: 10},
  success: function(data){
    $('#form').hide();
    $('#message').text('Search success!!');
    $('#LIST').html(data).fadeIn('fast');
  },
  error: function(){
    $('#message').text('Error on search');
  }
});
            

Configuration

Program thinking with configurations


// GOOD
var config: {
  messages = {
    success: 'Search success',
    error: 'Error on search'
  },
  api: {
    users: "api/users"
  },
  animate: {
    velocity: "fast"
  },
  list: {
    perPage: 10
  }
}
//...
$.ajax({
  type: "POST",
  url: config.api.users,
  data: {limit: config.list.perPage},
  success: function(data){
    $('#form').hide();
    $('#list').text(config.messages.success);
    $('#lista').html(data).fadeIn(config.animate.velocity);
  },
  error: function(){
    $('#message').text(config.messages.success);
  }
});
            

Avoid callback hell

Avoid callback hell


// KILL ME PLEASE
$('#button').on('click', function(){
  $.ajax({
    type: "POST",
    url: 'users',
    success: function(data){
      $('#result').fadeIn('fast', function(){
        $('#form').animate({
          heigth: 0, 
          opacity: 0
        }, 300, function(){
            $('#message').animate({
              heigth: 200,
              opacity: 1
            }, 300, function(){
              //etc etc
            })
          }
        )
      })
    },
    error: function(){
      $('#message').text(config.messages.success);
    }
  });
});
          

Avoid callback hell


// BETTER
('#button').on('click', function(){
  loadProducts()  
});

function loadProducts(){
  $.ajax({
    type: "POST",
    url: 'users',
    success: function(){
      showProducts();
      showMessage('Sucess');
    },
    error: showMessage('error')
  );
}

function showProducts(){
  ...
}

function showMessage(errorType){
  ...
}
          

Avoid touching DOM


// BAD
$('#buttonSend').on('click', function(){
  $(this).prop('disabled', true);
  $('$myForm').addClass('sending');
  $.post('ajax/contact', function(data) {
    $('#message').html(data);
    $('$myForm').removeClass('sending');
    $('#buttonSend'),prop('disabled', false);
  });
});

// BETTER
var $buttonSend = $('#buttonSend');
var $myForm = $('#myForm');
var $message = $('#message');

$buttonSend.on('click', function(){
  $buttonSend.prop('disabled', true);
  $myForm.addClass('sending');
  $.post('ajax/contact', function(data) {
    $message.html(data);
    $myForm.removeClass('sending');
    $buttonSend.prop('disabled', false);
  });
});
          

General

Avoid Globals

Don't use reserved words as keys.

Code consistency

Modularize your code

Think in configurations

Add functionality with javascript, not content

Development code

Avoid excessive optimization

Coding style

Use the literal syntax new objects and arrays.

Use single quotes '' for strings.

Don't use reserved words as keys.

Use single quotes '' for strings.

Use Array#join instead of string concatenation.

Dont declare a function in a non-function block (if, while)

Use dot notation when accessing properties `product.name` instead of `product['name']`

Declare unassigned variables last.

Coding style

Assign variables at the top of their scope

Use `===` and `!==` over `==` and `!=

Use braces with all multi-line blocks

`else if` dont exist in javascript

Use soft tabs set to 2 spaces.

Use indentation when making long method chains

Perform type coercion at the beginning of the statement.

Use `parseInt with a radix `parseInt(inputValue, 10);`

Code Organization

Key Concepts

Modules / Encapsulation

Divide the code into units of functionality — modules, services, etc.

Avoid the temptation to have all of your code in one huge block.

Encapsulation

Separate your application into distinct pieces of code and functionality

We can use 2 patterns for encapsulate code:

Object Literal

Object??

Everything is an object

exception for primives: Strings, Numbers, Booleans, null, undefined

Object Literal ??

{}

Regular anonymous function with jQuery


// Bad
$( document ).ready(function() {
  $( "#user_tabs li" ).click(function() {
      var $item = $( this );
      $('#content').load( $item.attr( "href" ), function() {
          $( "#user_tabs li" ).removeClass('active');
          $item.addClass('active');
      });
  });
});
            

Object Literal


// Better
var userModule = {

  init: function( settings ) {
    ...
  },

  bindClick: function(  ) {
    ...
  },

  loadContentTab: function() { 
  ... 
  },

  toggleTab: function() { 
  ... 
  }

}
            
WHY???

more verbose, but:

configurations outside logic

small methods

clear order of exection

no anonymous functions

Module Pattern

Private variables
FACADE / public methods

With IIFE

Immediately Invoked Function Expression

var userModule = (function() {

  var ABC;
  
  function sum1(){
    ABC = ABC + 1;
  }
  
  function sum2(){
    ABC = ABC + 2;
  }

  return ABC;
  
})();
            

FACADE


var userModule = (function() {

  var ABC;
  
  function sum1(){
    ABC = ABC + 1;
  }
  
  function sum2(){
    ABC = ABC + 2;
  }

  return {
    plus1: sum1,
    myValue: ABC;
  }
  
})();

userModule.plus1()
            

IIFE + FACADE + Object literal


var userModule = (function() {

  module = {
    ABC: 10,

    sum1: function(){
        module.ABC = module.ABC + 1;
    },

    sum2: function(){
        module.ABC = module.ABC + 2;
    },

  }

  return {
    plus1: module.sum1,
    myValue: module.ABC;
  }
  
})();

userModule.plus1()
            

IIFE + ~FACADE + Object literal


var userModule = (function() {

  var _public = {}
  var _private = {}

  _private.ABC =  10,

  _public.sum1 = function(){
        module.ABC = module.ABC + 1;
  }

  _private.sum2 = function(){
        module.ABC = module.ABC + 2;
  }

  return _public;
  
})();

userModule.sum1()
            

DRY

Don't Repeat Yourself

Identify similarities among pieces of functionality, and use inheritance techniques to avoid repetitive code.

Keep Things DRY

Don't repeat yourself.

Try to find pieces of code reusable and put in a function


// BAD
$( document ).ready(function() {
    $( "#tab1 button" ).click( function() { $.ajax( url1 ) });
    $( "#tab2 button" ).click( function() { $.ajax( url2 ) });
    $( "#tab3 button" ).click( function() { $.ajax( url3 ) });
});

// GOOD
$( document ).ready(function() {

    var bindButton = function(id){
      $( id ).click( loadResult });
    }
    var loadResult = function(url){
      $.ajax( url3 )
    }

    bindButton('tab1 button')
    bindButton('tab2 button')
    bindButton('tab3 button')

});
            

Loose Coupling

Units of functionality should be loosely coupled

Units of functionality should be able to exist on its own, and communication between units should be handled via a messaging system such as custom events or pub/sub

Code colaboration

Don't Fall in Love With Your Own Code!

Tools

JSCS

JSCS joint with jslint

with AirbnB presets!

Tests!

JEST / Mocha / Chai / Dalek

Legacy code

Caching selectors

Avoid look for the same element multiple times.


// BAD
$( "#tabs button1" ).click( function() { ... });
$( "#tabs button1" ).hover( function() { ... });

// GOOD
var $tabsButton1 = $( "#tabs button1" );
$tabsButton1.click( function() { ... });
$tabsButton1.hover( function() { ... });
            

Caching selectors

Better with chaining


// GOOD
var $tabsButton1 = $( "#tabs button1" );
$tabsButton1.click( function() { ... });
$tabsButton1.hover( function() { ... });
// BETTER
var $tabsButton1 = $( "#tabs button1" );
$tabsButton1
  .click( function() { ... });
  .hover( function() { ... });
            

In this case, we dont need the variable


// BETTER
var $tabsButton1 = $( "#tabs button1" );
$tabsButton1
  .click( function() { ... });
  .hover( function() { ... });
// EVEN BETTER
  $( "#tabs button1" );
    .click( function() { ... });
    .hover( function() { ... });
            

Caching selectors & scope

If we need bind in multiple buttons in same scope, store the parent;


// GOOD
var $tabsButton1 = $( "#tabs button1" );
var $tabsButton2 = $( "#tabs button2" );
$tabsButton1.click( function() { ... });
$tabsButton2.click( function() { ... });
// BETTER
var $tabs = = $( "#tabs button1" );
var $tabsButton1 = $tabs.find( "button1" );
var $tabsButton2 = $tabs.find( "button2" );
$tabsButton1.click( function() { ... });
$tabsButton2.click( function() { ... });
            

General tips

Stay up to date! Update the Jquery versions!

Use good practices even for small apps and inline page javascript

Choose the right selectors

Try to write one action for each line

Try to write one action for function

General tips

Dont store data on DOM


// BAD
$( "#user" ).data('updated', true);
$( "#user" ).addClass('updated');
var isUpdated = $( "#user" ).data('updated');
var isUpdated = $( "#user" ).hasClass('updated');
            

HTML/DOM should be a result of some operation

ES6 & ES7

Functional programming

REACT and others