EcmaScript 6

using es6 with babel

debugging mode

<script src="node_modules/babel-core/browser.js"></script>
<script type="text/babel">
// Your ES6 code
</script>

production mode

babel script.js --out-file script-compiled.js

Yifei’s Notes

the main impovements of ES6 are loops and generators, let/const, arrow functions, class syntax small pieces are function arguments, destructuring

Looping

there are 3 ways to loop a sequence in ES5, but there are problems

ES5 Loops

// not concise
for (var index = 0; index < myArray.length; index++) {
    console.log(myArray[index]);
}

// no break or return
myArray.forEach(function (value) {
    console.log(value);
});

// for objects, not arrays
for (var index in myArray) {
    // don't actually do this
    console.log(myArray[index]);
}

Introducing ES6 Loops

// concise and correct
for (let value of myArray) {
    console.log(value);
}

// also works on strings, sets and maps
for (let chr of "") {
    alert(chr);
}

// make a set from an array of words
 var uniqueWords = new Set(words);
for (let word of uniqueWords) {
  console.log(word);
}

for (var [key, value] of phoneBookMap) {
    console.log(key + "'s phone number is: " + value);
}


// you can even make it work with objects
// dump an object's own enumerable properties to the console
for (var key of Object.keys(someObject)) { console.log(key + ": " + someObject[key]); }

Generator

Inside a generator-function, yield is a keyword, with syntax rather like return. The difference is that while a function (even a generator-function) can only return once, a generator-function can yield any number of times. The yield expression suspends execution of the generator so it can be resumed again later.

Generator functions are basically the pause-and-continue-able function. when you call a generator function, it returns an paused Generator object, which has a next() function, each time you call the next() function, a pair of yielded-value and status is returned.

In technical terms, each time a generator yields, its stack frame—the local variables, arguments, temporary values, and the current position of execution within the generator body—is removed from the stack. However, the Generator object keeps a reference to (or copy of) this stack frame, so that a later .next() call can reactivate it and continue execution.

function* fibs() {
  var a = 0;
  var b = 1;
  while (true) {
    yield a;
    [a, b] = [b, a + b];
  }
}


function* range(start, stop) { for (var i = start; i < stop; i++) yield i; }

// This should "ding" three times
for (var value of range(0, 3)) {
  alert("Ding! at floor #" + value);
}

This is possible because generators are iterators. All generators have a built-in implementation of .next() and Symbol.iterator.

Template Strings

Hello ${user.name}, welcome to our server for the ${times} times

Rest Parameters and Defaults

ES5 version

function containsAll(haystack) {
  for (var i = 1; i < arguments.length; i++) {
    var needle = arguments[i];
    if (haystack.indexOf(needle) === -1) {
      return false;
  }
}
return true;
}

ES6 version

function containsAll(haystack, ...needles) {
  for (var needle of needles) {
    if (haystack.indexOf(needle) === -1) {
      return false;
  }
}
return true;
}

ES6 supports default parameters, The default argument gets evaluated at call time, so unlike e.g. in Python, a new object is created each time the function is called.

Class

ES6 support static method, supuer, getter/setter, you can even subclass builtin types

class Circle {
    constructor(radius) {
        this.radius = radius;
        Circle.circlesMade++;
    };

    static draw(circle, canvas) {
        // Canvas drawing code
    };

    static get circlesMade() {
        return !this._count ? 0 : this._count;
    };
    static set circlesMade(val) {
        this._count = val;
    };

    area() {
        return Math.pow(this.radius, 2) * Math.PI;
    };

    get radius() {
        return this._radius;
    };
    set radius(radius) {
        if (!Number.isInteger(radius))
            throw new Error("Circle radius must be an integer.");
        this._radius = radius;
    };
}

Array

var [,,third] = ["foo", "bar", "baz"];
var [head, ...tail] = [1, 2, 3, 4];
console.log(tail);
// [2, 3, 4]


var robotA = { name: "Bender" };
var robotB = { name: "Flexo" };

var { name: nameA } = robotA;
var { name: nameB } = robotB;

console.log(nameA);
// "Bender"
console.log(nameB);
// "Flexo"

// this is a syntax sugar for variable and key share the same name
var { foo, bar } = { foo: "lorem", bar: "ipsum" };
console.log(foo);
// "lorem"
console.log(bar);
// "ipsum"

var [missing = true] = [];
console.log(missing);
// true

var { message: msg = "Something went wrong" } = {};
console.log(msg);
// "Something went wrong"

var { x = 3 } = {};
console.log(x);
// 3

// parameters
function removeBreakpoint({ url, line, column }) {
  // ...
}


// super works as expected, calling super constructor and access base properties

// you can even subclass builtin types

CommonJS

There is a special object called module.exports, when requireing, the value of module.exports is returned.

something like that…

var require = function(path) {
    // ...
    return module.exports;
};

ES6 export

use the export keyword

// lib.js
export function foo() {}
export class bar {}
// or
export {baz, foz};
export {foo as fart};

// use.js
import {foo, bar} from "lib.js";
import {foo as fart} from "lib.js"; // renaming
import {* as lib} from "lib.js"; // import everything and put in a object

ES6 import commonJS

most packages are written in commonJS, for using as ES6 modules:
import _ from "lodash" // which is
import {default as _} from "lodash" // which is
let _ = require("lodash");

you can also do module.exports in ES6
export default value;

及时获取更新,请关注公众号“爬虫技术学习(spider-learn)”

公众号“爬虫技术学习(spider-learn)”

About 逸飞

后端工程师

发表评论

电子邮件地址不会被公开。 必填项已用*标注