Modern JavaScript cheatsheet

Defining Variables: let/const (better than var)

var will pollute the global object when called outside a function. (The global object = window in browser). In functions, they are function scoped and hoisted.

let/const will never pollute the global object. Also, they are block scoped. This means you can isolate let/const in a if, switch, while, or for block.

With let, you can reassign a variable. With const, you cannot reassign a variable. WARNING: you can still modify an object or array.

Boolean evaluation

falsy: false, 0, "", null, undefined, NaN
truthy: everything else (including [], {}, "0", "false")

Conditional Evaluation

All of these do short-circuiting (ie: won't try to evaluate eval2 if it doesn't need to)
eval1 || eval2
when eval1 is truthy, return eval1
                            else return eval2

eval1 && eval2
when eval1 is falsy, return eval1
                          else return eval2

eval1 ?? eval2
when eval1 is not null nor undefined, return eval1
                                                           else return eval2

test ? eval1 : eval2
when test is truthy, return eval1
                          else return eval2

Classes and “this”

In classes, the this keyword is determined by the caller. So with events, this will be undefined. To workaround, you can use binding in the constructor:

  this.method = this.method.bind(this);

Arrow Functions

You can use arrow functions instead of functions. this is determined by the enclosing container.

// both are equivalent
function add(a, b) {
  return a + b;
const add = (a, b) => {
  return a + b;

Shorter Arrow Syntax

If your arrow function only has a single return statement, you can remove it with the curly brackets for the function body.

const add = (a, b) => { return a + b; };
const add = (a, b) => a + b;  ­   //equivalent

If the param only has a single argument, then you can omit the round braces.

const double = (a) => a * 2;
const double = a => a * 2;  ­  //equivalent

Rest Parameters

function fn(a, b, ...theRest) {
  // theRest is an array containing all other arguments

Spread Syntax (Arrays, Functions and Objects)

Helps you create new arrays and objects. Also helps you call a function with an existing array.

const numbers = [5, 6, 7];

// spread an existing array into a new one,
// adding a new item at the end ⮯⮯
const moreNumbers = [...numbers, 8];

//this is an normal function ⮯⮯
function fn(a, b, c) { /* code here */ }

// calling previous fn with a spreaded array. ⮯⮯
const employee1 = { name: 'Eric', city: 'Montreal' };
const clonedEmp = { ...employee };  // clone an object
const employee2 = { ...employee, city: 'Dallas' };
// add property to cloned employee ⮭⮭

Destructuring (Arrays and Objects)

Helps you create variables by decomposing the values contained in arrays and objects.

const list = [1, 2, 3];
let [a, , b] = list; // a=1, b=3
[b, a] = [a, b];     // Swap the values, no temp var!

const emp = { firstName: 'Eric', lastName: 'Cote' };

// const firstName='Eric',  lastName='Cote' ⮯⮯
const { firstName, lastName } = emp;

// destructuring to alias surname='Cote' ⮯⮯
const { lastName: surname } = emp;

function fn({ firstName, lastName: surname }) {
  // destructuring right in fn args ⮭⮭

Export modules

Modules allows to export and import code right in javascript. There are two types of exports:

  • Default Export (only one per module)
  • Named Exports
export const x = 5, y = 6;
export function fn() {...};
export class ClassName {...}

// Export list ⮯⮯
export { name1, name2, name3};

// Renaming exports ⮯⮯
export { var1 as name1, var2 as name2};

// Exporting destructured assignments with renaming ⮯⮯
export const { name1, name2: bar } = obj;

// Default exports ⮯⮯
export default expression;
export default function (…) { … }      // also class
export default function name1(…) { … } // also class
export { name1 as default, … };

Import modules

Allows you to import code from exported modules. Below, only the first

import React from 'react'; // import the default export
import { useState } from 'react'; //import a named export

// import multiple named export ⮯⮯
import { Button, Input } from 'module-name';

//Use an alias to rename a named export ⮯⮯
import { Button as Btn } from 'react-bootstrap';

// get only what you need from specifice file
// (optimization) ⮯⮯
import { foo, bar } from 'module-name/un-exported/file';

// mix of more complex syntax⮯⮯
import { export1, export2 as alias2 } from 'module';
import defaultExport, { export1, export2 } from 'module';
import defaultExport, * as name from 'module';
import 'module';

// import all named export (expensive, avoid) ⮯⮯
import * as bootstrap from 'react-bootstrap';

// imperative syntax (instead of declarative) ⮯⮯
const promise = import('module');


A function variable will survive beyond the function scope when referred by an inner function that is returned. Usually, the scope of a var is the enclosing function. But here, the var stays scoped while the returned function stays referenced.

function outer() {
  let theVar = 42;
  return function inner() {
    return theVar;
const fn = outer();
console.log(fn()); //returns 42!
//theVar stays scoped while fn is reachable.
­//this is not the case in languages that
//don't support closures.

React Academy

To get the latest version of this document, visit the handout section of