Skip to content

Coding practices guide

Jérémie Astori edited this page Feb 13, 2015 · 13 revisions

Table of contents

Asynchronous computations

Examples

// The new readFile returns a promise rather than expecting a callback
var readFile = Promise.denodeify(require('fs').readFile);

Immutable data structures

Side-effects

  • Side-effects can be a cause of errors that are hard to track down.
  • Write pure functions, functions without side-effects.
  • Try to respect the following convention: if a function has side effects, it does not return anything.
  • Mutating an object is a side effect. Return a modified copy of an element rather than mutating the element itself.
// Good
function addElement(list, element) {
  return list.push(element); // Leaves list unchanged
}

// Bad
function addElement(array, element) {
  array.push(element); // Mutates array
  return array;
}

Functional traversal vs. imperative traversal

  • When traversing collections, make your code describe the "What" (you want to do) rather than the "How" (you want to do it). This leads to more meaningful code, focused on the actual behavior you wanted to achieve rather than the mechanics of traversing your collections. Mechanics are now abstracted. Code is also usually shorter and defines less temporary variables.
  • As a rule of thumbs, this means less to no uses of for and while loop, and more uses of map, reduce and filter functions.
  • This usually helps to separate concerns.

Examples

function double(x) { return 2 * x; }

// Good
[1, 2, 3, 4].map(double);

// Bad
function doubleArray(input) {
  var result = [];

  for (var i = 0; i < input.length; ++i) {
    result[i] = double(input[i]); // Only this line matters in the end...
  }

  return result;
}

imperativeDouble([1, 2, 3, 4]);
function isEven(x) { return x % 2 === 0; }

// Good
[1, 2, 3, 4].filter(isEven);

// Bad
function evenArray(input) {
  var result = [];

  for (var i in input) {
    if (isEven(i)) result.push(i); // Again, only this line is relevant
  }

  return result;
}

evenArray([1, 2, 3, 4]);

eval is Evil

  • Do not use eval.
  • eval has aliases:
    • Do not use the Function constructor.
    • Do not pass strings to setTimeout or setInterval.

Tests

  • Always provide tests.
  • Try to make your tests self-contained. Not doing so can result in unexpected behavior when running tests locally compared to when they are run on the CI instance.