JavaScript

Le langage dynamique incontournable.

References JavaScript

Let instead of var

If you must reassign references, use let instead of var. Why? let is block-scoped rather than function-scoped like var.

var count = 1;
if (true) {
 count += 1;
}
let count = 1;
if (true) {
 count += 1;
}

Classes and constructor

Always use class

Classes are a new feature in ES6, used to describe the blueprint of an object and make EcmaScript’s prototypical inheritance model function more like a traditional class-based language. So always use class. Avoid manipulating prototype directly. Why ? class syntax is more concise and easier to reason about.

function Queue(contents = []) {
 this.queue = [...contents];
}
Queue.prototype.pop = function () {
 const value = this.queue[0];
 this.queue.splice(0, 1);
 return value;
};
class Queue {
 constructor(contents = []) {
  this.queue = [...contents];
 }
 pop() {
  const value = this.queue[0];
  this.queue.splice(0, 1);
  return value;
 }
}

Extends for inheritance

Use extends for inheritance. Why? It is a built-in way to inherit prototype functionality without breaking instanceof.

class PeekableQueue extends Queue {
 peek() {
  return this.queue[0];
 }
}

Comparison operators and equality

Equality operators

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

With these operators, you can :

  • Comparing two literal values
  • Evaluating the value of typeof
  • Comparing against null

Coercion

Embrace implicit coercion when it makes sense. Avoid it otherwise.

if (x === undefined || x === null) { ... }
if (x == undefined) { ... } // Check if x is undefined and implicitly not null

Template strings

In traditional JavaScript, text that is enclosed within matching  » or ‘ marks is considered a string. Text within double or single quotes can only be on one line. There was no way to insert data into these strings. This resulted in a lot of ugly concatenation code that looked like:

var name = 'Sam';
var age = 42;
console.log('hello my name is ' + name + ' I am ' + age + ' years old');

ES6 introduces a new type of string literal that is marked with back ticks (`). These string literals can include newlines, and there is a string interpolation for inserting variables into strings:

var name = 'Sam';
var age = 42;
console.log(`hello my name is ${name}, and I am ${age} years old`);

Destructuring 

Object destructuring

Use object destructuring when accessing and using multiple properties of an object. Why? Destructuring saves you from creating temporary references for those properties.

function getFullName(user) {
 const firstName = user.firstName;
 const lastName = user.lastName;
 return firstName + ' ' + lastName;
}

Good

function getFullName(user) {
 const { firstName, lastName } = user;
 return `${firstName} ${lastName}`;
}

Better

function getFullName({ firstName, lastName }) {
 return `${firstName} ${lastName}`;
}

Array destructuring

const arr = [1, 2, 3, 4];
const first = arr[0];
const second = arr[1];
const arr = [1, 2, 3, 4];
const [first, second] = arr;

Functions

Never name a parameter arguments

This will take precedence over the arguments object that is given to every function scope.

function foo(name, options, arguments) {
 ...
}
function foo(name, options, args) {
 ...
}

Never use arguments

Opt to use rest syntax … instead.

function concatenateAll() {
 const args = Array.prototype.slice.call(arguments);
 return args.join('');
}
function concatenateAll(...args) {
 return args.join('');
}

Default parameter

Use default parameter syntax rather than mutating function arguments.

function handleThings(opts) {
 opts = opts || {};
 ...
}
function handleThings(opts) {
 if (opts === void 0) {
  opts = {};
 }
 ...
}
function handleThings(opts = {}) {
 ...
}

Always put default parameters last.

function handleThings(opts = {}, name) {
 ...
}
function handleThings(name, opts = {}) {
 ...
}

Arrow function

Fat arrow (or arrow function)

When you must use function expressions (as when passing an anonymous function), use arrow function notation. Why ? It creates a version of the function that executes in the context of this, which is usually what you want, and is more concise syntax.

[1, 2, 3].map(function (x) {
 const y = x + 1;
 return x * y;
});
[1, 2, 3].map((x) => {
 const y = x + 1;
 return x * y;
});

Functions that calculate a single expression and return its values can be defined even simpler:

incrementedItems = items.map(function (x) {
 return x+1;
});
incrementedItems = items.map((x) => x+1);

There is one important difference, however: arrow functions do not set a local copy of this, arguments, super, or new.target. When this is used inside an arrow function JavaScript uses the this from the outer scope.

Review My Order

0

Subtotal