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?
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;
}
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;
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){}
Avoid use javascript to create styles or content.
// BAD
$('.user-name').css({
'border' : '1px solid red',
'color' : 'red'
});
// GOOD
$('.user-name.error').addClass('error');
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;
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');
}
});
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);
}
});
// 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);
}
});
});
// 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){
...
}
// 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);
});
});
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
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.
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);`
Divide the code into units of functionality — modules, services, etc.
Avoid the temptation to have all of your code in one huge block.
Separate your application into distinct pieces of code and functionality
We can use 2 patterns for encapsulate code:
Object??
Everything is an object
exception for primives: Strings, Numbers, Booleans, null, undefined
Object Literal ??
{}
// 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');
});
});
});
// Better
var userModule = {
init: function( settings ) {
...
},
bindClick: function( ) {
...
},
loadContentTab: function() {
...
},
toggleTab: function() {
...
}
}
more verbose, but:
configurations outside logic
small methods
clear order of exection
no anonymous functions
var userModule = (function() {
var ABC;
function sum1(){
ABC = ABC + 1;
}
function sum2(){
ABC = ABC + 2;
}
return ABC;
})();
var userModule = (function() {
var ABC;
function sum1(){
ABC = ABC + 1;
}
function sum2(){
ABC = ABC + 2;
}
return {
plus1: sum1,
myValue: ABC;
}
})();
userModule.plus1()
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()
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()
Don't Repeat Yourself
Identify similarities among pieces of functionality, and use inheritance techniques to avoid repetitive code.
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')
});
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
JSCS joint with jslint
with AirbnB presets!
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() { ... });
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() { ... });
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() { ... });
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
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