前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深入理解ES6之——迭代器与生成器

深入理解ES6之——迭代器与生成器

作者头像
寻找石头鱼
发布2019-09-11 16:32:17
4210
发布2019-09-11 16:32:17
举报
文章被收录于专栏:寻找石头鱼

迭代器

迭代器是被设计专用于迭代的对象,带有特定接口。所有的迭代器对象都有next方法,会返回一个结果对象。该结果对象有两个属性:对应下一个值的value,以及一个布尔类型的done,其值为true时表示没有更多对值可供使用。

代码语言:javascript
复制
//es5创建迭代器
function createIterator(items) {
var i = 0;

return {
    next: function() {
        var done = (i >= items.length);
        var value = !done ? items[i++] : "undefined";

        return {
            done: done,
            value: value
        }
    }
}
}

var iterator = createIterator([1, 2, 3]);
console.log(iterator.next());//{done:false,value:1}
console.log(iterator.next());//{done:false,value:2}
console.log(iterator.next());//{done:false,value:3}
console.log(iterator.next());//{done:true,value:"undefined"}
console.log(iterator.next());//{done:true,value:"undefined"}

生成器

生成器是一个能返回迭代器的函数。生成器函数由放在function关键字之后的一个星号(*)来表示,并使用新的yield关键字(指定迭代器在被next()方法调用时应当按顺序返回的值。)。

代码语言:javascript
复制
function* createIterator() {
    yield 1;
    yield 2;
    yield 3;
}

var iterator = createIterator();

console.log(iterator.next());//{done:false,value:1}
console.log(iterator.next());//{done:false,value:2}
console.log(iterator.next());//{done:false,value:3}
console.log(iterator.next());//{done:true,value:undefined}
console.log(iterator.next());//{done:true,value:undefined}

生成器最有意思的方面可能就是它们会在每个yield语句后停止执行。

代码语言:javascript
复制
//yield语句在for循环中的使用
function* createIterator(items) {
    for (let i = 0, len = items.length; i < len; i++) {
        yield items[i];
    }
}

var iterator = createIterator([1, 2, 3]);

console.log(iterator.next());//{done:false,value:1}
console.log(iterator.next());//{done:false,value:2}
console.log(iterator.next());//{done:false,value:3}
console.log(iterator.next());//{done:true,value:undefined}
console.log(iterator.next());//{done:true,value:undefined}

yield只能用于生成器内部,用于其他任何位置都会报错,即使在生成器内部的函数中也不行。因为yield无法穿越函数边界。从这点上来说,yield与return非常相似。

代码语言:javascript
复制
function *createIterator(items){
    items.forEach(function(item){
        yield item+1;//语法错误
    })
}

生成器函数表达式

你可以使用函数表达式来创建一个生成器,只需要在function关键字与圆括号之间使用一个星号(*)即可。

生成器对象方法

代码语言:javascript
复制
var o = {
    *createIterator(items){
         for (let i = 0, len = items.length; i < len; i++) {
                yield items[i];
            }
    }
}

可迭代对象与for-of循环

可迭代对象被设计用于与es新增的for-of循环配合使用。

for-of循环在循环每次执行时会调用可迭代对象的next()方法,并将结果对象的value储存在一个变量上。循环过程会持续到结果对象的done属性编程true为止。

代码语言:javascript
复制
let values = [1, 2, 3];
for (let num of values) {
    console.log(num);
}

//输出内容为
1,2,3

let set = new Set([1, 3, 3, 2, 4, 5, 1, 3]);

for (let val of set) {
    console.log(val);
}

//输出内容为
1,3,2,4,5

let map = new Map();

map.set("name", "cc");
map.set("age", 26);

for (let val of map) {
    console.log(val);
}

//输出内容为
["name","nicolas"]
["age",52]

访问默认迭代器

你可以使用Symbo.iterator来访问对象上的默认迭代器。

代码语言:javascript
复制
let values = [1, 2, 3];

var iterator = values[Symbol.iterator]();

console.log(iterator.next());//{value:1,done:false}
console.log(iterator.next());//{value:2,done:false}
console.log(iterator.next());//{value:3,done:false}
console.log(iterator.next());//{value:undefined,done:true}

内置的迭代器

集合的迭代器

ES6具有三种集合对象类型:数组、Map和Set。这三种类型都拥有如下迭代器:

  1. entries():返回一个包含键值对的迭代器
  2. values():返回一个包含集合中值的迭代器
  3. keys():返回一个包含集合中键的迭代器
代码语言:javascript
复制
let colors = ["red", "green", "blue"];
let set = new Set([1234, 5678, 9012]);
let map = new Map();

map.set("title", "unde");
map.set("format", "ebook");

//entries
for (let entry of colors.entries()) {
    console.log(entry);
}
for (let entry of set.entries()) {
    console.log(entry);
}
for (let entry of map.entries()) {
    console.log(entry);
}

//values
for (let value of colors) {
    console.log(value);
}
for (let value of set.values()) {
    console.log(value);
}
for (let value of map.values()) {
    console.log(value);
}

//keys
for (let key of colors.keys()) {
    console.log(key);
}
for (let key of set.keys()) {
    console.log(key);
}
for (let key of map.keys()) {
    console.log(key);
}

字符串的迭代器

代码语言:javascript
复制
let message = "A  B";

for (let s of message) {
    console.log(s);
}

//输出内容为
A
(BLANK)
(BLANK)
B

NodeList的迭代器

代码语言:javascript
复制
let p = document.getElementsByTagName("p");

for (let c of p) {
    console.log(c.className);
}

传递参数给迭代器

代码语言:javascript
复制
function* createIterator() {
    let first = yield 1;
    let second = yield first + 2;
    yield second + 3;
}

let iterator = createIterator();
console.log(iterator.next());//1
console.log(iterator.next(4));//6
console.log(iterator.next(5));//8

在包含赋值操作的第一个yield语句中,表达式右侧再第一次调用next()时被计算,而表达式左侧则在第二次调用next()方法时,并在生成器函数执行之前被计算。

生成器委托

代码语言:javascript
复制
function* createNumI() {
    yield 1;
    yield 2;
}

function* createColI() {
    yield "red";
    yield "green";
}

function* createComb() {
    yield* createNumI();
    yield* createColI();
    yield true;
}

let iterator = createComb();

console.log(iterator.next());//{value:1,done:false}
console.log(iterator.next());//{value:2,done:false}
console.log(iterator.next());//{value:"red",done:false}
console.log(iterator.next());//{value:"green",done:false}
console.log(iterator.next());//{value:true,done:false}
console.log(iterator.next());//{value:undefined,done:false}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017-11-20 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 迭代器
  • 生成器
  • 生成器函数表达式
  • 生成器对象方法
  • 可迭代对象与for-of循环
  • 访问默认迭代器
  • 内置的迭代器
    • 集合的迭代器
    • 字符串的迭代器
    • NodeList的迭代器
    • 传递参数给迭代器
    • 生成器委托
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档