ES6新特性

ES6 新增了let命令,用来声明变量,但是所声明的变量,只在let命令所在的代码块内有效。代码块是{ }所包围的部分,即块级作用域

{{{{{let i = 'Hello World'}}}}}; //五个块级作用域

let有以下几个特性

  • 不存在变量提升,即在声明之前使用此变量会报错
  • let不允许在相同作用域内,重复声明同一个变量。

 

const

  • const声明一个只读的常量(具备let的特性)即声明的变量所指向的内存地址不会改变。

global

  • 在所有环境下,global都可以拿到顶层对象

数组解构赋值:从数组中提取值,按照对应位置,即有次序对变量赋值。

let [a, [b], d] = [1, [2, 3], 4];

无论左右形式是否完全匹配,都会把匹配的值赋值,不匹配的忽略(不完全解构

对象解构赋值

let { foo: baz } = { foo: "aaa", bar: "bbb" };
baz // "aaa"
foo // error: foo is not defined

对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。上面代码中,foo是匹配的模式,baz才是变量。真正被赋值的是变量baz,而不是模式foo。不完全解构也能实现。

let x;
({x} = {x: 1});//JavaScript 引擎会将{x}理解成一个代码块,从而发生语法错误。加个圆括号即可解决

字符串解构赋值

 

字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象。

const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"

//类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值。 let {length : len} = 'hello'; len // 5

 

数值和布尔值的解构赋值

解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。由于undefinednull无法转为对象,所以对它们进行解构赋值,都会报错。

函数参数的解构赋值

 符合上述解构。

function add([x, y]){
  return x + y;
}

add([1, 2]); // 3

函数add的参数表面上是一个数组,但在传入参数的那一刻,数组参数就被解构成变量xy

 

展开运算符(用三个连续的点 ( ... ) 表示)是 ES6 中的新概念,使你能够将字面量对象展开为多个元素。

const books = ["Don Quixote", "The Hobbit", "Alice in Wonderland", "Tale of Two Cities"];
console.log(...books);
//Don Quixote The Hobbit Alice in Wonderland Tale of Two Cities

 

剩余参数

剩余参数也用三个连续的点 ( ... ) 表示,使你能够将不定数量的元素表示为数组。

const order = [20.17, 18.67, 1.50, "cheese", "eggs", "milk", "bread"];
const [total, subtotal, tax, ...items] = order;
console.log(total, subtotal, tax, items);
//20.17 18.67 1.5 ["cheese", "eggs", "milk", "bread"]

 Promise

 

new Promise(function (resolve, reject) {
    window.setTimeout(function createSundae(flavor = 'chocolate') {
        const sundae = {};
        // request ice cream
        // get cone
        // warm up ice cream scoop
        // scoop generous portion into cone!
        resolve(sundae);
    }, Math.random() * 2000);
});

首先Promise 将立即返回一个对象,该对象上具有一个 .then() 方法,我们可以让该方法通知我们 promise 中的请求成功与否。.then() 方法会接收两个函数:

  1. 请求成功完成时要运行的函数
  2. 请求失败时要运行的函数
mySundae.then(function(sundae) {
    console.log(`Time to eat my delicious ${sundae}`);
}, function(msg) {
    console.log(msg);
    self.goCry(); // not a real method
});

Proxy

Proxy 对象介于真正的对象和调用代码之间。调用代码与 Proxy 交互,而不是真正的对象。要创建 Proxy:

  • 使用 new Proxy() 构造函数
    • 将被代理的对象传入为第一项
    • 第二个对象是 handler(处理器)对象
  • handler 对象由 13 种不同的 trap 之一构成
  • trap 是一种函数,将截获对属相的调用,让你运行代码
  • 如果未定义 trap,默认行为会被发送给目标对象

Proxy 是一种强大的创建和管理对象之间的交互的新方式。

 

可暂停的函数

如果我们希望能够中途暂停运行函数,则需要使用 ES6 中新提供的一种函数,叫做 generator(生成器)函数!我们来看一个示例:

function* getEmployee() {
    console.log('the function has started');

    const names = ['Amanda', 'Diego', 'Farrin', 'James', 'Kagure', 'Kavita', 'Orit', 'Richard'];

    for (const name of names) {
        console.log( name );
    }

    console.log('the function has ended');
}

 

注意到 function 关键字后面的星号(即 *)了吗?星号表示该函数实际上是生成器!生成器被调用时,它不会运行函数中的任何代码,而是创建和返回迭代器。该迭代器可以用来运行实际生成器的内部代码。关键字 yield 是 ES6 中新出现的关键字。只能用在生成器函数中。yield 会导致生成器暂停下来。

function* createSundae() {
    const toppings = [];

    toppings.push(yield);
    toppings.push(yield);
    toppings.push(yield);

    return toppings;
}

var it = createSundae();
it.next('hot fudge');//第一次调用
it.next('sprinkles');
it.next('whipped cream');
it.next();//因为第一次调用 .next() 传入了一些数据。但是该数据没有存储在任何位置。最后一次调用.next() 应该会获得一些数据,因为生成到对 toppings.push() 的最后一次调用中。

 

第一次调用 .next() 将初始化生成器,将在第一个 yield 位置暂停。第二次调用.next() 将向该 yield 提供数据。

posted @ 2018-01-27 14:27  白十三  阅读(170)  评论(0编辑  收藏  举报