Skip to content

Instantly share code, notes, and snippets.

@mwitek
Last active April 28, 2020 19:00
Show Gist options
  • Save mwitek/aa37e47b2546f994e387 to your computer and use it in GitHub Desktop.
Save mwitek/aa37e47b2546f994e387 to your computer and use it in GitHub Desktop.

ES6 cheat sheet, with very tasty examples

Declarations

let - prevents javascript hoisting to top of document, variables are scoped to function (no more undefined error when trying to call a var outside a functions scope, you get a ReferenceError which is more predictable/expected).

const - provides constants, cannot be redefined, raises syntax error

Function Arguments

You can now set default parameters in the function signature. The default value is used even if you explicitly pass in Undefined

example:

  let numberOfToppings = function(toppings=[]) {
    return toppings.length;
  };

  console.log(numberOfToppings()); //returns 0
  console.log(numberOfToppings(undefined)); //returns 0
  console.log(numberOfToppings(['cheese', 'onion'])); //returns 2

Named Parameters

Named parameters allow you to define default option properties in the method signature. This makes it easier to reason about how a function should be invoked and what options can be overridden.

example:

  let pizzaOrder = function(numberOfPizzas=0, {name, delivery}) {
   console.log(numberOfPizzas);
   console.log(name);
   console.log(delivery);
  };
  pizzaOrder(2, { name: 'Matt', delivery: false });
  //returns 2, 'Matt', false

  pizzaOrder(2, {});
  //returns 2, undefined, undefined

  pizzaOrder(2);
  // returns TypeError, we aren't passing the second argument and there isn't a default set.

You can set defaults for named parameters but the syntax isn’t as pretty so I thought I’d showcase the simpler version before this one which has defaults in place to prevent outputting undefined.

  let pizzaOrder = function(numberOfPizzas=1, {name, delivery}={name: 'anonymous', delivery: false}) {
   console.log(numberOfPizzas);
   console.log(name);
   console.log(delivery);
  };

  pizzaOrder(2, { name: 'Matt', delivery: true });
  //returns 2, 'Matt', true

  pizzaOrder(2);
  //returns 2, 'anonymous', false

For of loop

The for of loop allows you to iterate over property values without having to pass around the index for access.

Example:

let toppings = ['cheese', 'bacon', 'onion']

for(let topping of toppings) {
  console.log(topping);
};
//logs cheese, bacon, onion

Rest Parameters, (splats)

Rest Parameters allow you to pass an indefinite number of arguments as an array.

Example:

  let pizzaToppings = function(...toppings) {
    for(let topping of toppings) {
      console.log(topping)
    };
  };

  pizzaToppings('cheese');
  // returns cheese

  pizzaToppings('cheese', 'pepperoni', 'onion', 'tomato', 'bacon');
  //returns 'cheese', 'pepperoni', 'onion', 'tomato', 'bacon'

  pizzaToppings();
  // returns nothing as the for of loop never runs

It's important to note that the rest parameter must be declared last in the function signature.

If you have to call a function that uses rest parameters and you have an array of arguments, you can pass along the array with the spread operator attached.

  let toppings = ['cheese', 'onion', 'green pepper']
  pizzaToppings(...toppings);

The spread Operator will break up the array into individual arguments.

Arrow Functions

Arrow function are a way to manage the this keyword. They have a lexical binding and bind to the scope where they are defined and not where they run. Typically use case is a function callback.

example:

  let PizzaMaker = function(toppings, cookTime) {
    this.toppings = toppings;
    this.cookTime = cookTime;
  };

  let displayConfirmationMessage = function(callback) {
    callback();
  };

  PizzaMaker.prototype.bake = function(){
    displayConfirmationMessage(()=> {
      console.log(this.toppings);
      console.log(this.cookTime);
    });
  };

  let myPizza = new PizzaMaker('cheese', '20mins');

  myPizza.bake();
  //returns cheese and 20mins.. it has access to the original object properties.

Object Property Shorthand

You can use object property shorthand when your property name is the same as your variable name.

Example:

  let PizzaMaker = function(toppings, cookTime) {
    return { toppings, cookTime };
  };

  let myPizza = new PizzaMaker('cheese', '20mins');

  console.log(myPizza.toppings); //logs cheese
  console.log(myPizza.cookTime); //logs 20mins

You can also use this shorthand (object desructuring) to assign local variables from properties. You must use the object property key as the local variable name.

Example:

  let PizzaMaker = function(toppings, cookTime) {
    let flavoredCrust = true;
    return { toppings, cookTime, flavoredCrust };
  };

  let { toppings, cookTime } = new PizzaMaker('cheese', '20mins');

  console.log(toppings); //logs cheese
  console.log(cookTime); //logs 20mins
  
  let { flavoredCrust, somethingMadeUp } = new PizzaMaker('cheese', '20mins');
  console.log(flavoredCrust); //logs true
  console.log(somethingMadeUp); //logs undefined

Template Strings

Template strings are string literals that allow embedded expressions. It's very similar to coffeeScript string interpolation, just the syntax varies. You use backticks, a dollar sign and curly braces.

Example:

  let name = "Matt"
  console.log(`Hello, my name is ${name}`); //logs Hello, my name is Matt

Template strings also allow for multiline text and keep the newline character.

let letter = `Dear reader,

You'll notice that I set a new line above.

These are preserved in this block of text!`
  
console.log(letter); //logs
//Dear reader,

//You'll notice that I set a new line above.

//These are preserved in this block of text!

Object.assign

Merges objects together, If familar with jQuery this is the same as $.extend. You can chain as many objects as you like. When duplicate properties exist, the last object properties in the chain will prevail.

Example:

  let defaultPizza = {
    cheese: true
  };
  
  let myPizza = {
    cheese: false,
    pepperoni: true
  };
  
  let mergedPizza = Object.assign({}, defaultPizza, myPizza, { greenPepper: true }, {greenPepper: false});
  
  console.log(defaultPizza); //returns { cheese: true }
  console.log(myPizza); //returns { cheese: false, pepperoni: true }
  console.log(mergedPizza); //returns { cheese: false, pepperoni: true, greenPepper: false }

Array Destructuring

You can assign multiple values from an array to local variables

Example:

  let toppings = ['cheese', 'pepperoni', 'onion'];
  let [topping1, topping2, topping3] = toppings;
  console.log(topping1); //logs cheese
  console.log(topping2); //logs pepperoni
  console.log(topping3); //logs onion

Also, you can skip array items if needed. To do this you represent each index item that you want to skip with a space and a comma.

  let toppings = ['cheese', 'pepperoni', 'onion'];
  let [ , , topping] = toppings;
  console.log(topping); //logs onion

Array Find

Array.find returns the first element in an array if an element in the array satisfies the provided testing function. Otherwise undefined is returned.

Example:

  let toppings = ['cheese','bacon', 'onion'];
  let bacon = toppings.find((topping) => {
    return topping === 'bacon';
  });
  console.log(bacon);
  // logs bacon
  
  //with objects
  let pizzas = [
    { toppings: false, orderID: '1' },
    { toppings: true, orderID: '2' },
    { toppings: true, orderID: '3' },
  ];
  
  let firstPizzaWithToppings = pizzas.find((pizza) => {
    return pizza.toppings;
  });
  console.log(firstPizzaWithToppings);
  //returns { toppings: true, orderID: '2' }

Map Object

The Map object is a simple key/value object that allows any value (both objects and primitive values) to be used as either a key or a value. You use the set method to add entries and the get method to read entries. There are other methods such as clear to clear the map and has to check if a map contains a specific key.

Example:

  let order1 = { size: 'large', toppings:['cheese'] };
  let order2 = { size: 'small', toppings:['cheese'] };
  let totalCosts = new Map();

  totalCosts.set(order1, '19.99');
  totalCosts.set(order2, '9.99');
  console.log(totalCosts.get(order1)); // logs 19.99
  console.log(totalCosts.get(order2)); // logs 9.99
  console.log(totalCosts.has('my made up key')); //logs false

  totalCosts.clear();
  console.log(totalCosts.has(order1)); //logs false

You can also iterate maps with a for..of loop.

  let orders = new Map();
  orders.set('order-1', '19.99');
  orders.set('order-2', '9.99');
  for(let [key, value] of orders) {
    console.log(`${key} : ${value}`);
  };
  //returns order-1 : 19.99, order-2 : 9.99

Set Object

The Set object lets you store unique values of any type, whether primitive values or object references. You can also iterate over sets with for..of.

Example:

  let toppings = new Set();
  toppings.add('cheese');
  toppings.add('pepperoni');
  toppings.add('bacon');
  toppings.add('pepperoni');
  for(let topping of toppings) {
    console.log(topping)
  };
  //returns cheese, pepperoni, bacon
  //The last add('pepperoni') was ignored as the value was a duplicate

Classes

JavaScript classes are syntactical sugar over JavaScript's existing prototype-based inheritance. JavaScript classes provide a much simpler and clearer syntax to create objects and deal with inheritance. Your object properties are typically setup with the constructor methosd. There can only be one special method with the name "constructor" in a class.

Example:

  class Pizza {
    constructor(size, toppings) {
      this.size = size;
      this.toppings = toppings;
    }

    bake() {
      return `cooking a ${this.size} pizza.`;
    }
  }

  let myPizza = new Pizza('large', ['cheese', 'bacon']);

  console.log(myPizza.bake()); // returns cooking a large pizza.

Extends

The extends keyword is used in class declarations or class expressions to create a class with a child of another class.

Example:

  class PizzaBase {
    constructor(size, toppings=[]) {
      this.size = size;
      this.toppings = toppings;
    }
    
    bake() {
      return `cooking a ${this.size} pizza.`;
    }
  }

  class MeatLoversPizza extends PizzaBase {
    constructor(size) {
      super(size);
      this.toppings = ['bacon', 'pepperoni', 'sausage'];
    }
  }

  let myPizza = new MeatLoversPizza('large');

  console.log(myPizza.toppings); // returns bacon, pepperoni, sausage
  console.log(myPizza.bake()); // returns cooking a large pizza.

Modules

Modules provide a way to share methods throughout your app without polluting the global namespace. A module is an anonymous function that is exposed via the export keyword. When declared this way other pieces of code can use these functions via the import keyword.

Example:

  //lets pretend this function lives in a file named logger.js
  export default function(message) {
    console.log(message)
  }

  //now lets pretend we want to use this method in a file named pizza.js.
  //We can import the method like so:

  import myLogger from './logger';

  //now we have the logger function exposed in our pizza.js and can use it like so:
  myLogger('hello');
  
  //Note, since I used 'default' when declaring the export I can name it anything I
  //wish when importing... myLogger could have been myPizzaLoggerYum.

You can also exports multiple functions with a slightly different syntax.

//lets pretend these function lives in a file named logger.js
function consoleLogger(message) {
  console.log(message);
}

function alertLogger(message) {
  alert(message);
}

exports { consoleLogger,  alertLogger}

//now when importing you have to use the exact name declared in the export.
import { consoleLogger,  alertLogger} from './logger';

A nice use case for modules is constants.

  //lets pretend we are in a file named constants.js we can export constants like so:
  const MIN_TOPPINGS = 1;
  const MAX_TOPPINGS = 12;
  exports { MIN_TOPPINGS, MAX_TOPPINGS }
  
  //now that these are defined via export, we can import into any file via import.
  import { MIN_TOPPINGS, MAX_TOPPINGS } from './constants';

Promise Object

The Promise object is used for deferred and asynchronous computations. A Promise represents an operation that hasn't completed yet, but is expected in the future. The promise constructor takes in an anonymous function with two callback arguments, one argument for resolving and another for rejecting. Once a promise is fulfilled we can call then on it to read the results from the promise. If the promise is rejected then the execution moves immediately to the catch function.

Example:

let getOrderStatus = function(orderId) {
  return new Promise(resolve, reject) {
    let url = `/order/status/${orderId}`;
    let request = new XMLHttpRequest();
    
    request.open('GET', url, true);
    
    request.onload = function() {
      resolve(JSON.parse(request.response));
    };
    
    request.onerror = function() {
      reject(new Error('could not find order'));
    };
  }
};

let orderStatus = getOrderStatus(1);

orderStatus.then(function(result){
  console.log(result);
});

orderStatus.catch(function(error) {
  console.log(error);
});

Generator Object

A generator object is a way to create iterator objects. Once you have an interator object you can use for..of loops, the spread operator and destructuring assignments.

Example:

  function * toppings(){
    yield 'cheese';
    yield 'pepperoni';
  }

  for(let topping of toppings()){
   console.log(topping);
  }// logs cheese, pepperoni

  console.log([...toppings()]);// logs ['cheese','pepperoni']

  let [topping1, topping2] = toppings();
  console.log(topping1);// logs cheese
  console.log(topping2);// logs pepperoni
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment