CLEAN CODING

Formatting, Comments & variables

FORMATTING


const DAYS_IN_WEEK = 7;
const daysInMonth = 30;

const songs = ['Back In Black', 'Stairway to Heaven', 'Hey Jude'];
const Artists = ['ACDC', 'Led Zeppelin', 'The Beatles'];

function eraseDatabase() {}
function restore_database() {}

class animal {}
class Alpaca {}

SPOT THE PROBLEM


const DAYS_IN_WEEK = 7;
const DAYS_IN_MONTH = 30;

const songs = ['Back In Black', 'Stairway to Heaven', 'Hey Jude'];
const artists = ['ACDC', 'Led Zeppelin', 'The Beatles'];

function eraseDatabase() {}
function restoreDatabase() {}

class animal {}
class alpaca {}

USE CONSISTENT CAPITALIZATION

class PerformanceReview {
  constructor(employee) {
    this.employee = employee;
  }

  lookupPeers() {
    return db.lookup(this.employee, 'peers');
  }

  lookupManager() {
    return db.lookup(this.employee, 'manager');
  }


  getPeerReviews() {
    const peers = this.lookupPeers();
    // ...
  }

  perfReview() {
    this.getPeerReviews();
    this.getManagerReview();
    this.getSelfReview();
  }
  
  getManagerReview() {
    const manager = this.lookupManager();
  }

  getSelfReview() {
    // ...
  }
}

const review = new PerformanceReview(employee);
review.perfReview();

Is this easy to read?


class PerformanceReview {
  constructor(employee) {
    this.employee = employee;
  }

  perfReview() {
    this.getPeerReviews();
    this.getManagerReview();
    this.getSelfReview();
  }

  getPeerReviews() {
    const peers = this.lookupPeers();
    // ...
  }
  
  lookupPeers() {
    return db.lookup(this.employee, 'peers');
  }

  getManagerReview() {
    const manager = this.lookupManager();
  }
  
  lookupManager() {
    return db.lookup(this.employee, 'manager');
  }

  getSelfReview() {
    // ...
  }
}

const review = new PerformanceReview(employee);
review.perfReview();

Function callers and callees should be close

COMMENTS

function hashIt(data) {
  //the hash
  let hash = 0;

  //Length of string
  const length = data.length;

  //Loop through every character in data
  for (let i = 0; i < length; i++) {
    //get character code
    const char = data.charCodeAt(i);
    //make the hash
    hash = ((hash << 5) - hash) + char;
    // Convert to 32-bit integer
    hash &= hash;
  }
}
function hashIt(data) {
  let hash = 0;

  const length = data.length;

  for (let i = 0; i < length; i++) {
    const char = data.charCodeAt(i);
    hash = ((hash << 5) - hash) + char;
    // Convert to 32-bit integer
    hash &= hash;
  }
}

Only comment things that have business logic complexity

//BAD
doStuff();
//doOtherStuff()
//doSomeMoreStuff()
//doSoMuchStuff()

//GOOD
doStuff();

Don't leave commented out code in your codebase

////////////////////////////////////////
// Scope Model Instantiate
////////////////////////////////////////
$scope.model = {
  menu: 'foo',
  nav: 'bar'
};

///////////////////////////////////////
// Action setup
//////////////////////////////////////
const actions = function() {
  // ...
};

Positional Marker

$scope.model = {
  menu: 'foo',
  nav: 'bar'
};

const actions = function() {
  // ...
};

Avoid positional markers

Variables

// Use meaningful and pronounceable variable names
var yyyyymmddstr = moment().format('YYYY/MM/DD'); //BAD
var yearMonthDay = moment().format('YYYY/MM/DD'); //GOOD

// Use ES6 constants when variable values do not change
var firstUSPresident = "George Washington";  //BAD
const firstUSPresident = "George Washington";//GOOD


// Use searchable names
//BAD
for (var i = 0; i < 525600; i++) {  
  runCronJob();                                
}
//GOOD                                              
var minutesInAYear = 525600                 
for (var i = 0; i < minutesInAYear; i++) {
  runCronJob();
}

// Use explanatory variables
//BAD
const cityStateRegex = /^(.+)[,\\s]+(.+?)\s*(\d{5})?$/;
saveCityState(cityStateRegex.match(cityStateRegex)[1], cityStateRegex.match(cityStateRegex)[2])
//GOOD
const cityStateRegex = /^(.+)[,\\s]+(.+?)\s*(\d{5})?$/;
const match = cityStateRegex.match(cityStateRegex);
const city = match[1];
const state = match[2]
saveCityState(city, state);
// Don't add unneeded context
//BAD
var Car = {
  carMake: 'Honda',
  carModel: 'Accord',
  carColor: 'Blue'
};

function paintCar(car) {
  car.carColor = 'Red';
}
//GOOD
var Car = {
  make: 'Honda',
  model: 'Accord',
  color: 'Blue'
};

function paintCar(car) {
  car.color = 'Red';
}

// Short-circuiting is cleaner than conditionals
//BAD
var breweryName;
if (name){
 breweryName = name;
}else{
 breweryName = 'Hipster Brew Co.'
}
//GOOD
function createMicrobrewery(name) {
  var breweryName = name || 'Hipster Brew Co.';
}

Random Question

function foo1()
{
  return {
      bar: "hello"
  };
}

function foo2()
{
  return
  {
      bar: "hello"
  };
}

Consider the two functions below. Will they both return the same thing? Why or why not?

(function(){
  var a = b = 3;
})();

console.log("a defined? " + (typeof a !== 'undefined'));
console.log("b defined? " + (typeof b !== 'undefined'));

What will the code below output to the console and why?

(function() {
    console.log(1); 
    setTimeout(function(){console.log(2)}, 1000); 
    setTimeout(function(){console.log(3)}, 0); 
    console.log(4);
})();

What is the output?

Clean Coding

By Syafiq bin abdul rahman