0.0.1 • Published 4 years ago

publicissapient-javascript-styleguide v0.0.1

Weekly downloads
5
License
GPL-3.0
Repository
github
Last release
4 years ago

PublicisSapient Javascript Styleguide

A Javascript styleguide written from an enterprise perspective.

Table of Contents

Accessors

MDN web docs:

ESLint rules:

Accessors are more commonly referred to as getters and setters. The get and set syntax binds an object property to a function that will be called when that property is looked up or assigned a value.

This pattern looks promising but has too many drawbacks to be used on a large project. Spelling mistakes will not trigger errors with set calls. This can be avoided by using normal functions instead of getters and setters.

  // bad
  class User {
    constructor() {
      this.firstName = 'Ada';
      this.lastName = 'Lovelace';
    }

    get fullName() {
      return `${this.firstName} ${this.lastName}`;
    }

    set fullName(value) {
      const names = value.split(' ');
      this.firstName = names[0];
      this.lastName = names[1];
    }
  }

  var user = new User();

  // An error will be thrown for spelling mistakes on getters
  // TypeError: undefined is not a function
  console.log(user.fulName);

  // However since an object property can be named anything it will not be
  // thrown on setters
  user.fulName = 'Edith Clarke';

  // good
  class User {
    constructor() {
      this.firstName = 'Valerie';
      this.lastName = 'Taylor';
    }

    getFullName() {
      return `${this.firstName} ${this.lastName}`;
    }

    setFullName(value) {
      const names = value.split(' ');
      this.firstName = names[0];
      this.lastName = names[1];
    }
  }

  var user = new User();

  // An error will be thrown for spelling mistakes on getters
  // TypeError: undefined is not a function
  user.getFulName();

  // An error will also be thrown here as well
  user.setFulName('Margaret Hamilton');

  // And it's more obvious that you're calling a function like this
  user.setFullName('Radia Perlman');

Arrays

MDN web docs:

ESLint rules:

Create arrays using the literal notation instead of the constructor.

  // bad
  const planets = new Array();

  // good
  const planets = [];

Don't use spaces after open and before close brackets when creating an array.

  // bad
  const planets = [ 'Mercury', 'Venus', 'Earth' ];

  // good
  const planets = ['Mercury', 'Venus', 'Earth'];

If there are more than 5 elements in an array use line breaks to put each value on their own line.

  // bad
  const planets = ['Mercury', 'Venus', 'Earth', 'Mars', 'Jupiter', 'Saturn'];

  // bad
  const planets = ['Mercury', 'Venus', 'Earth',
    'Mars',
    'Jupiter',
    'Saturn'
  ];

  // good
  const planets = [
    'Mercury',
    'Venus',
    'Earth',
    'Mars',
    'Jupiter',
    'Saturn'
  ];

  // good
  const planets = [
    {
      name: 'Mercury',
      color: 'red'
    },
    {
      name: 'Venus',
      color: 'blue'
    },
    {
      name: 'Mars',
      color: 'red'
    },
    {
      name: 'Earth',
      color: 'blue'
    },
    {
      name: 'Jupiter',
      color: 'brown'
    },
    {
      name: 'Saturn',
      color: 'orange'
    }
  ];

Get the value of an item in an Array by using the index.

  const venus = planets[1];
  const earth = planets[2];

Loop through Arrays using the forEach method

  planets.forEach((planet, index) => {
    console.log(planet.name, index);
  });

Add items to an Array using the push method.

  planets.push({
    name: 'Mercury',
    color: 'red'
  });

Combine two or more Arrays using ... notation.

  const array1 = [1, 2, 3];
  const array2 = [4, 5, 6];

  const combinedArray = [...array1, ...array2];
  // expected output: [1, 2, 3, 4, 5, 6]

Create an Array from any array-like iterable using from. Array-like iterables include things like: String, Set, Map, and arguments.

  // create an array from a String
  const letters = Array.from('mars');
  // expected output: ['m', 'a', 'r', 's']

Use a return statement with Array methods every, filter, find, findIndex, map, reduce, reduceRight, some, sort.

  const numbers = [1, 2, 3];

  // check if all the items in the Array are less than 10 with .every()
  const allLessThanTen = numbers.every(element => {
    return element < 10;
  });
  // expected output: true

  // Create a new Array with all the items in the Array that are greater than
  // 1 with .filter()
  const greaterThanOne = numbers.filter(element => {
    return element > 1;
  });
  // expected output: [2, 3]

  // find the first item greater than 1 with .find()
  const first = numbers.find(element => {
    return element > 1;
  });
  // expected output: 2

  // find the index of the first item greater than 1 with .findIndex()
  const firstIndex = numbers.findIndex(element => {
    return element > 1;
  });
  // expected output: 1

  // Create a new Array with double all the numbers in the Array with .map()
  const doubleNumbers = numbers.map(element => {
    return element * 2;
  });
  // expected output: [2, 4, 6]

  // calculate the sum of all items using .reduce()
  const sum = numbers.reduce((accumulator, element) => {
    return accumulator + element
  });
  // expected output: 6

  // check if at least one item in the Array is less than 10 with .some()
  const someLessThanTen = numbers.some(element => {
    return element < 10;
  });
  // expected output: true

  // sort a list of words by their length with .sort()
  const sortedWords = ['Gladys', 'Mae', 'West'].sort((a, b) => {
    // if returned value is less than 0 then 'a' is sorted before 'b'
    // otherwise 'b' is sorted before 'a'
      return a.length - b.length;
  });
  // expected output: ['Mae', 'West', 'Gladys']

Strings

MDN Web Docs:

ESLint Rules:

Use single quotes '' for strings.

// bad
const name = "Ada Lovelace";

// good
const name = 'Grace Hopper';

// good - this applies to strings in other places like import and require statements as well
import myModule from './myModule';
const myOtherModule = require('./myOtherModule');

Really long strings should be written as a single line and leave any line wrapping to the IDE or code editor.

// bad
const melbaRoyMouton = 'Melba Roy Mouton (1929-1990) was an African-American \
woman who served as Assistant Chief of Research Programs at NASA\'s Trajectory \
and Geodynamics Division in the 1960s and headed a group of NASA \
mathematicians called "computers". Starting as a mathematician, she was head \
mathematician for Echo Satellites 1 and 2, and she worked up to being a Head \
Computer Programmer and then Program Production Section Chief at Goddard Space \
Flight Center.';

// bad
const dorothyVaughan = 'Dorothy Johnson Vaughan (September 20, 1910 – November 10, 2008) ' +
 'was an African American mathematician and human computer who worked for the National ' +
 'Advisory Committee for Aeronautics (NACA), and NASA, at Langley Research Center in ' +
 'Hampton, Virginia. In 1949, she became acting supervisor of the West Area Computers, ' +
 'the first African-American woman to supervise a group of staff at the center.';

// good
const katherineJohnson = 'Katherine Coleman Goble Johnson (born August 26, 1918) is an American mathematician whose calculations of orbital mechanics as a NASA employee were critical to the success of the first and subsequent U.S. crewed spaceflights. During her 35-year career at NASA and its predecessor, she earned a reputation for mastering complex manual calculations and helped pioneer the use of computers to perform the tasks. The space agency noted her "historical role as one of the first African-American women to work as a NASA scientist".';

Use template strings instead of concatenation when building up strings programatically.

const astronaut = 'Ellen Ochoa';

// bad - don't use string literals templates if you don't have any embedded expressions
const astronaut = `Ellen Ochoa`;

// bad
const goal = 'When I grow up I want to be an astronaut like ' + astronaut + '!';

// bad
const goal = ['When I grow up', 'I want to be', 'an astronaut', 'like', astronaut, '!'].join(' ');

// good
const goal = `When I grow up I want to be an astronaut like ${astronaut}!`;

Do not use template string notation inside of regular strings. The output is not technically wrong however it is more than likely an unintentional mistake.

const astronaut = 'Jenni Sydey';

// bad
const goal = 'When I grow up I want to be like ${astronaut}!';
// expected output: 'When I grow up I want to be like ${astronaut}!'

// good
const goal = `When I grow up I want to be like ${astronaut}!`;
// expectec output: 'When I grow up I want to be like Jenni Sydey!'

Only escape characters in strings that actually require escaping.

// bad - the double quotes don't need escaping
const anneMcClain = 'Anne\'s \call sign is \"Annimal\"';

// good
const anneMcClain = 'Anne\'s call sign is "Annimal"';

Global

ESLint Rules:

Never use eval() in any circumstance. It is an enormous security risk.

// bad
console.log(eval('2 + 2'));
// expected output: 4

// bad
console.log(eval(new String('2 + 2')));
// expected output: 2 + 2

// bad
console.log(eval('2 + 2') === eval('4'));
// expected output: true

Whitespace

ESLint rules:

Use a space before the opening brace of a block.

  // bad
  function test(){
    console.log('test');
  }

  // good
  function test() {
    console.log('test');
  }

Do not use a space between the argument list and the function name in function calls and declarations.

  // bad
  function marco () {
    console.log ('polo');
  }

  // good
  function marco() {
    console.log('polo');
  }

Use a space before opening parenthesis in control statements (if, while, etc.).

  // bad
  if(condition) { ... }

  // good
  if (condition) { ... }

Use spaces between operators.

  // bad
  const a=b+10;

  // good
  const a = b + 10;

Use a space after commas.

  // bad
  const list = [1,2,3,4]
  function fullName (firstName,lastName) { ... }

  // good
  const list = [1, 2, 3, 4]
  function fullName (firstName, lastName) { ... }

Do not leave multiple blank lines.

  // bad
  const value = 'hello world';


  console.log(value);

  // good
  const value = 'hello world';
  console.log(value);

Leave a blank line between a block and the next statement.

  // bad
  if (valid) {
    return value;
  }
  return message;

  // good
  if (valid) {
    return value;
  }

  return message;
  // bad
  const dog = {
    run() {
    },
    bark() {
    },
  };
  return obj;

  // good
  const dog = {
    run() {
    },

    bark() {
    },
  };

  return obj;

Comparison Operators & Equality

MDN web docs:

ESLint rules:

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

Use shortcuts for booleans, but explicit comparisons for strings and numbers

  // bad
  if (isLoaded === true) { ... }

  // good
  if (isLoaded) { ... }

  // bad
  if (value) { ... }

  // good
  if (value !== '') { ... }

  // bad
  if (items.length) { ... }

  // good
  if (items.length > 0) { ... }

Do not nest ternary expressions

  // bad
  const thing = foo ? bar : baz === qux ? quxx : foobar;
  // good
  const thing = foo ? bar : foobar;

  // good
  let thing;

  if (foo) {
    thing = bar;
  } else if (baz === qux) {
    thing = quxx;
  } else {
    thing = foobar;
  }

Do not use ternary expressions when simpler alternatives exist

  // bad
  const isEven = (value % 2 === 0) ? true : false;

  // good
  const isEven = value % 2 === 0;


  // bad
  const isOdd = (value % 2 === 0) ? false : true;

  // good
  const isOdd = value % 2 !== 0;
  // bad
  const value = newNumber ? newNumber : 1;

  // good
  const value = newNumber || 1;