Skip to content

jshipster/js-farts

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 

Repository files navigation

Javascript Code Smells

Introduction

In computer programming, code smell is any symptom in the source code of a program that possibly indicates a deeper problem. According to Fowler, "a code smell is a surface indication that usually corresponds to a deeper problem in the system" - Code Smell - Wikipedia

Bottom line, we need to refactor code with smells to make it more maintainable and reduce the number of bugs it introduces.

Table of Contents

  1. Purposeless conditions
  2. Multiple return statements
  3. This or That

Purposeless conditions

Synopsis

Purposeless conditions introduce unwanted complexity to the code. It also increases the vertical length of the function subtracting the readablity.

Avoid

  /* Example # 1 */
  function isNumber(test){
    if(typeof test === 'number')
      return true;
    else
      return false;
  }

  /* Example # 2 */
  function isNotBoolean(test){
    var retVal = false; //or any other initialization
    if(typeof test === 'boolean'){
      retVal = false;
    }
    else{
      retVal = true;
    }
    return retVal;
  }

Score

  /* Example # 1*/
  function isNumber(test){
    return typeof test === 'number';
  }
  
  /* Example #2 */
  function isNotBoolean(test){
    return typeof test !== 'boolean';
  }

Multiple return statements

Synopsis

There should generally be a single returning path from a function. Multiple return statements make it difficult to understand the flow of the function.

Avoid

  /* Example */
  function stringAdd(numString){
    var val = parseInt(numString);
    if(numString === NaN){
      return 0;
    }
    else{
      return val;
    }
  }

Score

  /* Example */
  function stringAdd(numString){
    var val = parseInt(numString);
    return val === NaN ? 0 : val;
  }

This or That

Synopsis

Assigning this to a variable is a general practive to maintain context in a function. This works but stinks and makes the code less recognizeable. Using constructs bind, call and apply to set context while calling a function is a more cleaner approach. Functions like forEach have a hidden parameter to set execution context.

Avoid

  /* Example 1*/
  function haircut(persons){
    var that = this;
    
    persons.forEach(function(person){
      that.cut(person);
    });
  }

Score

  /* Example 1*/
  function haircut(persons){
    persons.forEach(function(person){
      this.cut(person);
    }.bind(this));
  }
  
  /* Example 1 Alternate*/
  function haircut(persons){
    persons.forEach(function(person){
      this.cut(person);
    }, this); //hidden param to set context in `forEach`
  }

Contribution

Send in your PRs in the following pattern:

  • Let there be a pattern

Releases

No releases published

Packages

No packages published