All notes
Es6

Intro

byteArcher.com.

ES6 = ECMAscript2015 = ES2015.

ECMAScript is a specification of a language. JavaScript is an implementation of that language among JScript and ActionScript.

Features

TBD: template strings, Promises.

arrow functions

developer.mozilla.org.

An arrow function expression has a shorter syntax than a function expression and does not have its own this, arguments, super, or new.target. These function expressions are best suited for non-method functions, and they cannot be used as constructors.

Two factors influenced the introduction of arrow functions: shorter functions and non-binding of this.



// ----- Basic Syntax

(param1, param2, …, paramN) => { statements }
(param1, param2, …, paramN) => expression
// equivalent to: (param1, param2, …, paramN) => { return expression; }

// Parentheses are optional when there's only one parameter name:
(singleParam) => { statements }
singleParam => { statements }
singleParam => expression

// The parameter list for a function with no parameters should be written with a pair of parentheses.
() => { statements }

// ----- Advanced Syntax

// Parenthesize the body of function to return an object literal expression:
params => ({foo: bar})

// Rest parameters and default parameters are supported
(param1, param2, ...rest) => { statements }
(param1 = defaultValue1, param2, …, paramN = defaultValueN) => { statements }

// Destructuring within the parameter list is also supported
let f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
f();  
// 6

curried function

SO.



// First, examine this function with two parameters
let add = (x,y) => x + y;
add(2,3); //=> 5

// Here it is again in curried form …
let add = x => y => x + y;

add (2) // returns (y => 2 + y)
// In order to use our curried function, we have to call it a bit differently:
add(2)(3); // returns 5

var, let, const

let

Mozilla Developer.

let allows you to declare variables that are limited in scope to the block, statement, or expression on which it is used. This is unlike the var keyword, which defines a variable globally, or locally to an entire function regardless of block scope.


function varTest() {
  var x = 1;
  if (true) {
    var x = 2;  // same variable!
    console.log(x);  // 2
  }
  console.log(x);  // 2
}

function letTest() {
  let x = 1;
  if (true) {
    let x = 2;  // different variable
    console.log(x);  // 2
  }
  console.log(x);  // 1
}

Use let in for loop:


var list = document.getElementById("list");

for (let i = 1; i <= 5; i++) {
  let item = document.createElement("li");
  item.appendChild(document.createTextNode("Item " + i)); // If "var", i will still be 1-5.

  item.onclick = function (ev) {
    console.log("Item " + i + " is clicked."); // If "var", i will always be 6.
  };
  list.appendChild(item);
}

If you use var here, i in the onclick() function will always be 6.

Create a private interface without using closures:


var SomeConstructor;

{
    let privateScope = {};

    SomeConstructor = function SomeConstructor () {
        this.someProperty = "foo";
        privateScope.hiddenProperty = "bar";
    }

    SomeConstructor.prototype.showPublic = function () {
        console.log(this.someProperty); // foo
    }

    SomeConstructor.prototype.showPrivate = function () {
        console.log(privateScope.hiddenProperty); // bar
    }

}

var myInstance = new SomeConstructor();

myInstance.showPublic();
myInstance.showPrivate();

console.log(privateScope.hiddenProperty); // error

Temporal dead zone

In ECMAScript 2015, let will hoist the variable to the top of the block. However, referencing the variable in the block before the variable declaration results in a ReferenceError. The variable is in a "temporal dead zone" from the start of the block until the declaration is processed.


function do_something() {
  console.log(foo); // ReferenceError
  let foo = 2;
}

const

Mozilla.

The const declaration creates a read-only reference to a value. It does not mean the value it holds is immutable, just that the variable identifier cannot be reassigned. For instance, in case the content is an object, this means the object itself can still be altered.

A common convention is to use all-uppercase letters for const variables.


// define MY_FAV as a constant and give it the value 7
const MY_FAV = 7;

// The following will ALL throw an error:
MY_FAV = 20; // Can't change.
const MY_FAV = 20; // Can't redefine.
// The name MY_FAV is reserved for constant above, so this will also fail
var MY_FAV = 20;
let MY_FAV = 20;

// It's important to note the nature of block scoping
if (MY_FAV === 7) { 
    // this is fine and creates a block scoped MY_FAV variable 
    const MY_FAV = 20;
    // MY_FAV is now 20
    console.log("my favorite number is " + MY_FAV);

    // this gets hoisted into the global context and throws an error
    var MY_FAV = 20;
}

// MY_FAV is still 7
console.log("my favorite number is " + MY_FAV);

// Assigning to A const variable is a syntax error
const A = 1; A = 2;

// throws an error, missing initializer in const declaration
const FOO; 

// const also works on objects
const MY_OBJECT = {"key": "value"};
// Attempting to overwrie the object throws an error
MY_OBJECT = {"OTHER_KEY": "value"};
// However, object keys are not protected, so the following statement is executed without problem
MY_OBJECT.key = "otherValue"; // Use Object.freeze() to make object immutable

// The same applies to arrays
const MY_ARRAY = [];
// It's possible to push items into the array
MY_ARRAY.push("A"); // ["A"]
// However, assigning a new array to the variable throws an error
MY_ARRAY = ["B"]

Destructuring assignment

SO: js es6 const with curly braces.

It is an ES2015 destructuring assignment. It's a syntatically terse way of extracting properties from objects, into variables. It unpacks values from arrays, or properties from objects, into distinct variables. developer.mozilla.org.


// you can rewrite this
const name = app.name;
const version = app.version;
const type = app.type;

// as this
const { name, version, type } = app;

//----------

var a, b, rest;
[a, b] = [10, 20];
console.log(a); // 10
console.log(b); // 20

[a, b, ...rest] = [10, 20, 30, 40, 50];
console.log(a); // 10
console.log(b); // 20
console.log(rest); // [30, 40, 50]

({ a, b } = { a: 10, b: 20 });
console.log(a); // 10
console.log(b); // 20

// Stage 3 proposal
({a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40});
console.log(a); // 10
console.log(b); // 20
console.log(rest); //{c: 30, d: 40}

Best practice

medium.

`const` is a signal that the identifier won’t be reassigned.

`let`, is a signal that the variable may be reassigned, such as a counter in a loop, or a value swap in an algorithm. It also signals that the variable will be used only in the block it’s defined in, which is not always the entire containing function.

`var` is now the weakest, and should be avoided as possible.

typeof is no longer safe

es-discourse.com.



if (condition) {
  console.log(typeof value);     // ReferenceError!
  let value = "blue";
}
typeof x doesn't throw for var x but throws for let x is because var not only creates but also initializes binding to undefined, whereas let merely declares it.

import, export

See "commonjs.note" for more.

http://davidbcalhoun.com/2014/what-is-amd-commonjs-and-umd/ amd, commonJs, umd http://stackoverflow.com/questions/16521471/relation-between-commonjs-amd-and-requirejs AMD is more suited for the browser, because it supports asynchronous loading of module dependencies. RequireJS is an implementation of AMD, while at the same time trying to keep the spirit of CommonJS (mainly in the module identifiers). https://zhuanlan.zhihu.com/p/23493436 Prefer yarn than npm.

Importing modules using "require", and exporting using "module.exports" and "exports.foo". Importing modules using ES6 "import", and exporting using ES6 "export".

voidCanvas.com.



//-----CommonJS

//dep.js
dep = {
    foo: function(){},
    bar: 22
}
module.exports = dep;

// app.js
var dep = require("dep");
console.log(dep.bar);
dep.foo();
 
//-----ESM: ECMAScript Modules.

//dep.js
export foo function(){};
export const bar = 22;
 
//app.js
import {foo, bar} from "dep";
console.log(bar);
foo();
 

Rest Parameters

odeToCode.com: features of es6.


let doWork = function(name, ...numbers){
    let result = 0;
     
    numbers.forEach(function(n){
        result += n;
    });
 
    return result;
};

let result = doWork("Scott", 1, 2, 3);
expect(result).toBe(6);

Before ES6, we could use the implicit variable arguments, which is an array-like object, but is not an array, which creates confusion. It is also difficult to spot if a function is using arguments without reading through the code or documentation for the function.

Spread

odeToCode.com: spread.


let doWork = function(x, y, z) {
    return x + y + z;
}
var result = doWork(...[1, 2, 3]);
expect(result).toBe(6);

var a = [4, 5, 6]; 
var b = [1, 2, 3, ...a, 7, 8, 9]; 
expect(b).toEqual([1,2,3,4,5,6,7,8,9]);

Object Rest/Spread Properties for ECMAScript



//----- Rest Properties
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
x; // 1
y; // 2
z; // { a: 3, b: 4 }

//----- Spread Properties
let n = { x, y, ...z };
n; // { x: 1, y: 2, a: 3, b: 4 }