Understanding ECMAScript6(下)

2017-03-02  本文已影响0人  Michael_lpf


Part 1: ES6 中的类

基本类的声明

Paste_Image.png
👆sayName 方法被指派到原型上,接下来用 new 创建了一个 PersonType 的一个实例 person,如此,这个对象是通过原型继承了 PersonType 与 Object 的实例。
仍有值得主要的不同之处

类的表达式

需计算的成员名

类方法也可以使用可计算的名称,用 [] 包裹名称👇

Paste_Image.png
生成器方法

可以为对象定义一个生成器方法。
使用 * 配合方法名称,书写方法和对象字面量中定义生成器是一样的👇

Paste_Image.png
当对象需要存些值并要求可做些简单的迭代时,生成器方法很有效。
于是,我们可以用 Symbol.iterator 来写一个默认迭代器,迭代更方便👇
Paste_Image.png
静态成员

派生类


Part 2: Promise


Promise 基础

使用 Promise 对象构造一个实例👇

Paste_Image.png
👆接受一个被称为执行器的函数作为参数,该函数接受两个函数 resolvereject 作为参数。
实例化后,使用 then() 方法指定异步操作结果的回调函数。
Promise 生命周期

Promise 的生命周期初始为 pending state ,此时异步操作尚未结束。一旦操作结束,状态转为 resolved(成功结束) 或 rejected(未成功结束)。

内部的 [[PromiseState]] 属性在这个过程中被设置为 pending 后转换为 resolvedrejected) 以反映 Promise 的状态。
这个属性无法手动判断,但我们可以通过 then() 方法来指定状态改变时可以做的一些事情。


then() 方法和 catch() 方法

then() 方法存在于所有 Promise 实例上,接受两个参数,第一个参数用来指定 Promise 状态由 pending 转为 resolved 时做的事(异步完成了);第二个参数用来指定 Promise 状态由 pending 转为 rejected 时做的事(异步被拒绝了)。

传递给 then() 参数是可选的👇

//  处理完成和拒绝
pro.then(function(content){
    console.log(content);
}, function(error){
    console.log(error);
});
//  只处理完成
pro.then(function(content){
    console.log(content);
});
//  只处理拒绝
pro.then(null, function(error){
    console.log(error);
});

Promise 还有一个 catch() 方法,它的行为和只处理拒绝的例子是一样的👇

pro.catch(function(error){
    console.log(error);
})
//  等同于
pro.then(null, function(error){
    console.log(error);
});

如果被拒绝了,但没有指定如何处理,拒绝还是会静默发生👇


Paste_Image.png
建议始终附加一个拒绝处理函数, 即使该处理程序只是用于打印错误日志  —— Nicholas

catch() 方法还可以这样使用,在 Promise 的执行器中抛出一个错误,外部的拒绝处理函数会被调用👇

Paste_Image.png
串联 Promise

then()catch() 的调用实际上创建并返回了另一个 Promise。

当前一个 Promise 完成或被拒绝时,后一个 Promise 开始工作。
这个特性允许我们使用一组串联起来的 Promise 。

Paste_Image.png

串联中的 Promise 也可以捕获上一个Promise 中抛出的错误👇

Paste_Image.png

若是拒绝处理函数抛出的错误,同样可以在接下来捕获👆


在 Promise 链中返回值

执行器中传递给 resolve 函数的参数会被传递给对应的完成处理函数👇


Paste_Image.png

可以指定完成函数的返回值,这就可以沿着 Promise 链继续传递数据👇


Paste_Image.png
如果是拒绝处理函数也可以完成同样的事情👇
Paste_Image.png

💡 如此看,若有必要,可以用失败的 Promise 传递参数来恢复整个 Promise 继续运行。


响应多个 Promise
Paste_Image.png Paste_Image.png

Part 3:模块封装代码


在 ES6 之前,一个应用的每个 JS 文件所 定义的所有内容都由全局作用域共享。
ES6 的设计目标之一就是 要解决作用域问题。  —— Nicholas
模块特点s

基本的导出

使用 export 关键字公开功能给其它模块👇

// 导出变量
export let name = 'Pacino';
export const country = 'Italy';
export var address = 'New York';

// 导出类
export class Rectangle{
    constructor(length, width){
        this.length = length;
        this.width = width;
    }
}

// 导出函数
export function sum(num1, num2){
    return sum = num1 + num2;
}

// 声明的函数,不做导出,外部无法访问
function sum(num1, num2){
    return sum = num1 - num2;
}

// 导出一个函数
function foo(){
    return true;
}
// 稍后导出它
export { foo };

👆除了 export 关键字以外,每个声明与平时没什么不同。
💡 无法用这种方法导出匿名函数或匿名类,除非使用 default (稍后再说)


基本的导入

使用 import 关键字引入模块。

// 导入单个绑定
import { sum } form './test.js';

// 导入多个绑定
import { name, country, address } from './test.js';

// 完全导入
// test.js 中暴露出的模块如今都可以使用了
import * as test from './test.js';

重命名的导出和导入

可以使用 as 关键字来为导出和导入的模块重命名👇

// foo 函数被作为 myFunc 导出
function foo(){
    return true;
}
export { foo as myFunc };

👆而在“接收端”(👈我自己起的名字),导入这个函数时则是要接收 myFunc 这个函数而不是 foo 函数了。

在“接收端”,同样可以重命名后导入👇

import { foo as myFunc} from './test.js';

模块默认值

使用 default 关键字指定模块中的默认导出👇

// 这个函数成为了模块中的默认导出内容
export default function foo(){
    return true;
}

// 另一种默认导出的写法
function foo(){
    return true;
}
export { foo as default };

💡 若模块中有多个导出,并需要默认导出,第二种写法是很好的方法。

导入默认内容,去掉 {} 👇

import app from './test.js';

无绑定的导入

之前介绍的导入,都是有指定的内容的,或是默认的内容的,也就是有绑定的导入。
当然我们还可以做无绑定的导入👇

import './test.js';

语法非常简单。
写在导出模块中的内容也不需要添加 export 关键字了。
下面是一个书中的例子:

// 没有导出与导入的模块
Array.prototype.pushAll = function(items) {
    // items 必须是一个数组
    if (!Array.isArray(items)) {
        throw new TypeError("Argument must be an array.");
    }
    // 使用内置的 push() 与扩展运算符
    return this.push(...items);
};

导出模块中的方法,直接拿来用👇

import "./example.js";

let colors = ["red", "green", "blue"];
let items = [];

items.pushAll(colors);


本节完
Understanding ECMAScript6(上)
Understanding ECMAScript6(中)

上一篇 下一篇

猜你喜欢

热点阅读