MVP Standards and Process

JavaScript and jQuery

This document provides an overview of standards and best practices for handling JS.

Table of Contents

Terminology

Primitives Types

The following are primitive types in JavaScript

New in ES6 and newer JS specs

Complex Types

Arrays

Syntax

// Array Literal (Preferred)
const someArray = [1, 2, 3];

// Array Constructor
const someArray = new Array(1, 2, 3);

// Accessing an array
someArray[0] // 1

Array Methods

const someArrayLikeList = {0: 'foo', 2: 'bar' };

// Array.from
const x = Array.from(someArrayLikeList);

// Array.map
[1, 2, 3].map(function(num) {
    return num + 1;
});
// [2, 3, 4]

// Array.reduce
[1, 2, 3].reduce(function(acc, item, index) {
    return acc + item;
});
// 6

// Array.filter
[1, 2, 3].filter(function(num) {
    return num === 2;
});
// [2]

Objects

Objects are used to store keyed collections of data. It is preferred to use dot notation to access object data.

// Object Literal (Preferred)
const someObject = {
    key: 'value'
};

// Object Constructor
const someObject = new Object();

// Accessing an object
someObject.key // 'value'

Functions

Unnamed Functions

// Anonymous self calling function
// aka IIFE (Immediately-Invoked Function Expression)
(function() {
    /* ... */
})();

// Assigning an unnamed function to a variable
const variableName = function(y) {
    /* ... */
};

// Using an unnamed function as a callback
button.addEventListener('click', function() {
    /* ... */
});

Named Functions

// Standard named function
function foo() {
    /* ... */
}

// Named function expression
const foo = function bar() {
    /* ... */
}

// Functions as the value in an object. (Using object method shorthand).
{
    key: 'value',

    foo() {
        /* ... */
    }
}
Arrow Functions

When using an anonymous function it is preferred for it to be done using arrow function notation. Arrow functions are more concise and readable. They also simplify scope by using this from the scope in which they are created.

Read more about Arrow Functions here.

// These two functions are the same
const arrowFn = (x) => {
    return x + 1;
}

const arrowFn = x => x + 1;

// Arrow functions operate in the scope there are created, which allows for the following differences.

let x = 1;

(() => x + 1)(); // x = 2

// Versus this...
let x = 1;

(function() { x + 1; })(); // x = 1

References

There are three primary reference keywords.

Whenever possible use const for all your references and avoid using var. This ensures that you can not reassign your references, which leads to bugs and confusing code. Note that like let below, const is block-scoped.

If you need to reassign a reference use the let keyword (instead of var). This is because let is block-scoped. Read more about let here.

// Bad
var x = 1;

if (true) {
    x = 2;

    console.log(x); // 2
}

console.log(x); // 2

// Good
let x = 1;

if (x === 1) {
  let x = 2;

  console.log(x); // 2
}

console.log(x); // 1

Strings

Use single quotes '' for strings

// Bad
const variableName = "some string";

// Good
const variableName = 'some string';

Never use eval() on a string!

// Bad, bad, bad
console.log(eval('some evil function'));

General

We use the standard ESLint Recommended Config and suggest using a editor plugin to lint against those standards. This is also the standard bundled by default with Roots Sage WordPress Theme.

jQuery

Prefix jQuery variables with a $

This serves to as a reminder that the variable being accessed contains jQuery methods.

// Bad
const badName = $('.Class');

// Good
const $goodName = $('.Class');

Cache jQuery lookups

There are performance and readability benefits from caching jQuery lookups, by assigning the result to a variable.

// Bad
$('.Header').show();
$('.Header').hide();
$('.Header').css({
    // ...
});

// Good
const $profileHeader = $('.Header');

$profileHeader.show();
$profileHeader.hide();
$profileHeader.css({
    // ...
});