Skip to content

Latest commit

 

History

History
251 lines (189 loc) · 8.06 KB

js-ecmascript-6.md

File metadata and controls

251 lines (189 loc) · 8.06 KB

let and const

  • let declarations are not hoisted.
  • If there's a var in an if block, it will be declared outside the block to the nearest function scope. let limits its scope to inside the block (which, if you like brackets, makes some sense)
  • lets cannot be declared in the same scope twice. So, you cannot use lets in multiple switch statements.
    • You can use for(let i = 0;...) to limit i to the for block, and jshint won't complain like it does for var.
    • You can also use let to directly make a block: let(foo='bar', baz='buz') { /* use foo inside */}
  • const does NOT mean immutable. If you const an object, it is still mutable; the const itself just cannot be reassigned.

Arrays and array-like things

[for (x of ANY_ARRAY) for (y of ANY_ARRAY) for (z of ANY_ARRAY) (x + y + z)];  // unlimited number of `for`s

// these two are the same in what they do:
[console.log(t, a) for ({title: t, author: a} of books)];
[for (book of books) console.log(book.title, book.author)];

New methods

  • The equivalent to all() is .every(): let bar: boolean = array.every(x => isTrue(x))
  • The equivalent to any() is .some(): let bar: boolean = array.some(x => isTrue(x))

Destructuring

  • Destructuring assignment:
var [m, d, y] = [3, 14, 1977];  // need to wrap both in array notation
var [,,y] = [3, 14, 1977];  // can ignore variables you don't need

Destructuring objects

let luke = { occupation: 'jedi', father: 'anakin' }
let {occupation, father} = luke;
console.log(occupation); // 'jedi'
console.log(father); // 'anakin'

Such a destructure can be nested:

let {a: {b: c}} = {a: {b: 5}};  // c is now 5

It can also be done with brackets (let (a, b, c) = {'a': ..., ...}). Do note that this can have a special case with just one unpack:

const { foo } = {foo: 'bar'};  // foo is bar because you unpacked foo from the object

AND the special case where you unpack to nothing:

const {} = 'abc';  // "OK, strings are coercible to objects"
const {} = undefined;  // Error

Function signatures are no special case. They also automatically destructure an object:

function getFullName({ firstName, lastName })  // Extracts firstName and lastName from the first argument object

Functions

  • Spread (packing) and Rest (unpacking):
function foo(a, b, ...rest) { /* rest is an array */ }
foo(...[1,2,3,4,5]);
  • Arrow notation: only =>, no ->, and no context binding.
array.map((p) => p * 2);
array.reduce((p, q) => (p + q));  // example with two arguments

arguments cannot be used inside arrow functions, much like this cannot be.

var a = (foo) => {
    return foo;
};

a(3)  // 3
function foo(bar=5) {
    console.log(bar);
}
function foo({x, y=5}) {  // note: object notation (y:5) is not valid syntax at this particular location
    console.log(x);  // 4
}
foo({x: 4, y: 5})
{
  hello() {
    // ...
  },
  'hello world'() {
    // ...
  }
}

is equivalent to

{
  hello: function () {
    // ...
  },
  'hello world': function () {
    // ...
  }
}

and a clutch to adding dynamic names is, for some reason, done with square brackets:

let foo = 'foo'
const obj = {
  [foo + 'bar']: true
}

Classes

Proxies: a virtual wrapper that can handle property reads and changes on the original object.

var engineer = { name: 'Joe Sixpack', salary: 50 };

var interceptor = {
  set: function (receiver, property, value) {
    console.log(property, 'is changed to', value);
    receiver[property] = value;
  }
};

engineer = Proxy(engineer, interceptor);
  • Getter and setters in object shorthands:
{
  get hello() { ... }
  set hello() { ... }
}

was previously available with an awkward syntax in ES5.

  • Generators require that ugly asterisk after function:
   // The asterisk after `function` means that
   // `objectEntries` is a generator
   function* objectEntries(obj) {
        let propKeys = Reflect.ownKeys(obj);

        for (let propKey of propKeys) {
            // `yield` returns a value and then pauses
            // the generator. Later, execution continues
            // where it was previously paused.
            yield [propKey, obj[propKey]];
        }
    }

    for (let [key,value] of objectEntries(jane)) {
        console.log(`${key}: ${value}`);
    }

Imports

Imports and default imports are similar, the only difference being whether the import is wrapped in braces.

export default function () { return 4 }
export function foo() { return 5 }
// ---
import CallItAnything, {foo} from 'that_file';
CallItAnything();  // 4
foo();  // 5

Default imports can be mixed with named imports on a single line.

export default function () { .. this is React }
export function Component () { ... }
export function PropTypes () { ... }
---
import React, { Component, PropTypes } from 'react';
===
import React from 'react';
import { Component, PropTypes } from 'react';
===
Importing the default export under the name "React"
Importing the two named exports under the same names
  • You can also import * from 'a library'.
  • You cannot import dynamic paths. (In python, you __import__(dynamic).)
  • require('a library') is slower than imports, as the latter can be optimised statically.
  • import is not available in node 6.

Async/Await (ES7)

  • async functions always return a promise. A return 5 in an async function returns a promise that resolves with 5.
  • async functions always reject with the error if an error is thrown in it.
  • await asyncFunction() always returns the value that the function resolves.

Only in an async-marked function can you use await. An await in a non-async function throws a SyntaxError. If a promise is resolved, then the lines after await run. Otherwise, it throws an error and any catch blocks run. If an async function has multiple return points: since a promise can only resolve once, it will always resolve with the first value.

ES 2017

  • RegExp will now support negative lookahead, which uses (?<!foo) to ensure a pattern is not preceded by another pattern. (?<!foo)bar will never match foobar.