《ECMAScript6入门》整理(下)

9、Iterator和for…of循环

Iterator

部署了next方法的对象,就具备了遍历器功能。next方法必须返回一个包含value和done两个属性的对象。value是当前位置的值,done表示遍历是否结束

function makeIterator(array){
        var nextIndex = 0;
        return{
            next:function(){
                return nextIndex <array.length?{value:array[nextIndex ++],done:fale}:{value:undefined,done:true
                };
            }
        }
    }       

for…of循环

    for(var n of it){
        if(n>5)
             break;
        console.log(n);
    }//0,1,2,3,4,5

for…of 默认是从0开始的
数组原生具备iterator接口
for…in 只能获取键名(数组的键名是 0,1,2,3….)
for…in 可以遍历一般对象的属性名

10、Generator函数

含义

Generator就是个内部状态遍历器。
Generator函数有两个特征
1、function关键字后面有个星号
2、函数体内部使用yield语句定义遍历器的每个成员,即不同的内部状态

    function* helloWorldGenerator(){
        yield 'hello';
        yield 'world';
        return 'ending';
    }
    var hw = helloWorldGenerator();
    hw.next(); //{value:'hello',done:false}
    hw.next(); //{value:'world',done:false}
    hw.next(); //{value:'ending',done:true}
    hw.next(); //{value:undefined,done:true}

上面代码定义了一个Generator函数helloWorldGenerator,它的遍历器有两成员“hello”和“world”。调用这个函数,就会得到遍历器。

当Generator函数调用的时候,该函数并不执行,而是返回一个遍历器(可以理解成暂停执行)。以后每次调用这个遍历器的next方法,就从这个函数的头部或者上一次停下来的地方开始执行,直到遇到下一条yield语句为止,也就是说,next方法就是在遍历yield语句定义的内部状态。

Generator函数的本质是一种可以暂停执行的函数,yield语句就是暂停的标识。next方法遇到yield,就会暂停后面的操作,并将紧跟在yield后面的那个表达式的值,作为返回对象的value属性的值

next方法的参数

yield语句本书并没有返回值,next方法可以带一个参数,该参数会被当成上一条yield语句的返回值

    function* f(){
        for(let i = 0 ; true ; i++){
            let reset = yield i;
            if(reset){ i = -1};
        }
    }
    let g = f();
    g.next()//{value:0,done:false}
    g.next()//{value:1,done:false}
    g.next(true)//{value:0,done:false}

当next没有参数时,yield语句总是返回undefined,当有参数“true”时,变量reset就被置为-1;

异步操作的应用


Generator函数的这种暂停执行效果,意味着可以把一步操作放进yield语句里面,等到next调用时再去执行

function* longRunningTask(){
        yield step1();
        yield step2();
        yield step3();
        //...
        yield stepN();
    }
    scheduler( longRunningTask());
    function scheduler(task){
        setTimeout(function(){
             if(!task.next().done){
                 scheduler(task);
            }
        },0);
    }

使用一个函数,就可以按次序执行所有操作了
for…of循环可以自动遍历Generator函数,此时,不再需要调用用next方法

yield*语句


如果yield命令后面跟的是一个遍历器,则需要在yield后面加上*,表明它返回的是一个遍历器。

11、Promise对象


基本用法


Promise的好处是,可以将异步异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。

    var promise = new Promise(function(resolve,reject){
        if(/*异步操作成功*/){
            resolve(value);
        }else{
            rejrct(error);
        }
    });
    promise.then(function(value){
        //success
    },function(value){
        //failure
    });

上面的代码表示,Promise构造函数,接收一个函数作为参数,该函数的两个参数分别是resolve和reject方法。如果异步操作运行成功,则用resolve方法将Promise对象的状态变为成功(即从pending变为resolved);否则将Promise状态改为失败(即从pending变为rejected)

catch方法:捕捉错误


catch方法是then(null,rejection)的别名,用于指定错误发生时的回调函数。Promise对象的错误具有“冒泡性质”,会一直向后传递,知道被捕获为止。

Promise.all方法


Promise.all方法用于将多个异步操作(或Promise对象),包装成新的Promise对象,这些异步操作都完成后,新的Promise对象状态才变成fulfilled,只要有一个异步操作失败,则其状态就是rejected

Promise.resove方法


将现有的对象转换成Promise对象。如果Promise.resove方法的对象不是一个具有then方法的对象,则返回一个新Promise对象,且它的状态是recolved

async函数


用来代替回调函数的一种方法。只要函数名之前加上async关键字,就表明该函数内部有异步操作。该异步操作应该返回一个Promse对象。前面用await关键字注明。

function timeout(ms){
    return new Promise((resolve)=>{
        setTimeout(resolve,ms);
        });
    }
    async function asyncValue(value){
        await timeout(50);
        return value;
    }

12、Class和Module

class

ES6引入了类这个概念,作为对象模板,通过class关键字可以定义类。this、super、constructor不在多说

Module的基本用法


export和import


import用于输入其他模块提供的功能,同时创造命名空间,防止函数名冲突。在一个js文件中可以通过export关键字输出变量

    export var firstName = 'David';
    export var lastName = 'Belle';
    export var year= 1999;

等效于

    var firstName = 'David';
    var lastName = 'Belle';
    var year= 1999;
    export {firstName ,lastName ,year}

使用export定义模块后,其他js文件就可以通过import引入模块了

import{firstName ,lastName ,year} from './profile';

import关键字接收一个对象,里面指定要从其他模块中引入的变量。大括号里的变量名必须与被导入模块的变量名相同。如果想为输入的属性或方法换一个名字那么:

import{someMethod,another as NewName} from './exporter';

模块的整体加载

export除了输出变量,还可以输出方法和类

//circle.js
export function area(radius){
    return Math.PI*radius * radius
}
export function circumferencr(radius){
    return 2* Math.Pi*radius;
}

然后,在main.js中引入这个模块

//main.js
import{area,circumferencr} from 'circle'

或者整体导入

//main.js
module circle from 'circle';

module 后跟一个变量,表示导入模块定义在该变量上

export default语句

不想为某个方法或属性指定输入名称,可以使用export default语句。一个模块只能有一个默认方法。

模块继承


模块也可以继承。
假设有一个circleplus模块,继承了circle模块

//circleplus.js 
export * from 'circle';
export  var e =2.71828182846;
export default function(x){
    return Math.exp(x);
}

上面的export* 表示输出circle模块的所有属性和方法。
export default 定义了定义了模块的默认方法。
可以对circle中的方法改名后再输出

export {area as circleArea } from ‘circle’;

加载上面模块的写法如下

//main.js
module math from“circleplus”;
import exp from "circleplus";
console.log(exp(math.pi));

上面的import exp表示,将circleplus中默认方法加载为exp方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值