JavaScript is what everyone calls the language, but the official name of JavaScript is ECMAScript. That name comes from the standards organization Ecma, which manages the language standard. ECMAScript 1 (June 1997) was the first version of the JavaScript language standard.

Up until now, you've mostly been writing ECMAScript 5. ES5 is comfortable and familiar, but ES6 gives us a lot of great new features, which we'll start learning about this week.

Intuitive and flexible destructuring of Objects into individual variables during assignment.

function shorthandPropertyNames() {
  const red = Math.floor(Math.random() * 256);
  const green = Math.floor(Math.random() * 256);
  const blue = Math.floor(Math.random() * 256);
  return { red, green, blue };
  // instead of
  return {
    red: red,
    green: green,
    blue: blue,
  };
}

console.log(shorthandPropertyNames());

In ES5, you put values into strings by concatenating those values and string fragments:

function printCoord(x, y) {
  console.log("(" + x + ", " + y + ")");
}

In ES6 you can use string interpolation via template literals:

function printCoord(x, y) {
  console.log(`(${x}, ${y})`);
}

Template literals also help with representing multi-line strings:

const HTML5_SKELETON = `
    <!doctype html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
    </body>
    </html>`;

Destructuring is a convenient way of extracting multiple values from data stored in (possibly nested) objects and arrays.

// Object destructuring
const obj = { first: "Jane", last: "Doe" };
const { first, last } = obj; // first = "Jane"; last = "Doe"
const { first: f, last: l } = obj; // f = "Jane"; l = "Doe"

const state = { counter: 1, list: ["a", "b"] };
// no object destructuring
const list = state.list;
const counter = state.counter;
// object destructuring
const { list, counter } = state;
// Array destructuring
const iterable = ["a", "b"];
const [x, y] = iterable; // x = "a"; y = "b"

Pick what you need

If you destructure an object, you mention only those properties that you are interested in:

const { x: x } = { x: 7, y: 3 }; // x = 7

If you destructure an Array, you can choose to only extract a prefix:

const [x, y] = ["a", "b", "c"]; // x="a"; y="b";

Another great feature is the rest destructuring. It is often used for splitting out a part of an object, but keeping the remaining properties in another object. MDN: Rest parameters

const state = { counter: 1, list: ["a", "b"] };

// rest destructuring
const { list, ...rest } = state;

console.log(rest);
// output: { counter: 1 }
console.log(list);
// output: ["a", "b"]

The spread operator comes with three ..., but shouldn"t be mistaken for the rest operator. It depends on the context where it is used. Used within a destructuring (see above), it is as rest operator. Used somewhere else it is a spread operator. MDN: Spread syntax

let arr = [-1, 5, 11, 3];
console.log(Math.max(...arr));

Another example to append an array to another array:

const arr1 = ["a", "b"];
const arr2 = ["c", "d"];

arr1.push(...arr2);
// arr1 is now ["a", "b", "c", "d"]

Or to concatenate Arrays:

const x = ["a", "b"];
const y = ["c"];
const z = ["d", "e"];

const arr = [...x, ...y, ...z]; // ["a", "b", "c", "d", "e"]

ES6 gives us more ways to handle parameters.

Default parameters:

function f(x, y = 7, z = 42) {
  return x + y + z;
}

f(1); // 50

Rest parameter:

function f(x, y, ...a) {
  return (x + y) * a.length;
}
f(1, 2, "hello", true, 7); // 9

ES6 introduced arrow functions, which allow us to write functions with shorter syntax.

To name an arrow function, you must save it as a variable. If the function has only one statement, and the statement returns a value, you can remove the brackets and the return keyword:

function getFive() {
  return 5;
}
// Arrow function that has no parameter and returns value by default
const getFive = () => 5;

function divide(a, b) {
  return a / b;
}
// Arrow function with parameters
const divide = (a, b) => a / b;

Multiple lines or expressions in an arrow function require the curly braces {} and the keyword return

const squared = (x) => {
  console.log(x);
  return x * x;
}; // block
const squared = (x) => x * x; // expression

Summary

Arrow functions are handy for one-liners. They come in two flavors:

  1. Without curly braces: (...args) => expression - the right side is an expression: the function evaluates it and returns the result.
  2. With curly braces: (...args) => { body } - brackets allow us to write multiple statements inside the function, but we need an explicit return to return something.

In regular functions the this keyword represented the object that called the function, which could be the window, the document, a button or whatever. When a function is called as a method of an object, its this is set to the object the method is called on.

var obj = {
  foo: function () {
    return this;
  },
};

obj.foo() === obj; // true

Arrow functions have no

this. this in arrow functions is determined by the surounding scope.

let person = {
  name: "Jack",
  age: 25,
  sayName: function () {
    console.log(this.age);
    let innerFunc = () => {
      console.log(this.age);
    };
    innerFunc();
  },
};
person.sayName();

You should not use arrow functions to create methods inside objects:

let person = {
  name: "Jack",
  age: 25,
  sayName: () => {
    // this refers to the global .....
    console.log(this.age);
  },
};

person.sayName(); // undefined

Summary