ES6之Iterable

ES6之Iterable

Iterable是ES6引入的一个新的类型。主要用于集合,对象的遍历。

一.引入的原因

  1. array可以使用下标遍历,而map,set不能使用下标遍历,集合类型不统一。
  2. 对于for…in…循环,当添加额外的属性后,会有意象不到的结果。
    var array = [1,2,3];
    array.name = 'name';
    //for...in...遍历的是对象的属性。Array也是一个对象,他的每个元素的索引视为一个属性
    for(var key in array) {
        console.log(key);  //0 1 2 name
    }
    

因此,为了统一结合类型,ES6标准引入了新的iterable类型,统一使用iterable的for…of…循环进行遍历。

二.for…of…

for…of…是ES6新引入的语法,实现iterable的它的用法如下:

var array = [1,2,3];
var set = new Set(array);
var map = new Map([[0,'a'], [1,'b'], [2,'c']]);

for(var item of array) {
    console.log(item);
}
// 1
// 2
// 3
for(item of set) {
    console.log(item)
}
// 1
// 2
// 3
for(item of map) {
    console.log(item[0]+ ' ' + item[1]);
}
// 0 a
// 1 b
// 2 c

for…of…循环修复了for…in…循环遍历属性的问题(但是不包括Array的length属性)。它只遍历集合本身的元素。

forEach遍历

forEach是ES5.1引入的语法,forEach函数接受一个回调函数,每次迭代都会自动调用该函数。

forEach遍历的使用方法

var array = [1, 2, 3];
var set = new Set(array);
var map = new Map([[1,'a'],[2,'b'],[3,'c']]);

array.forEach(function (value,index,array) {
    console.log(value,index,array);
    // 1 0 [ 1, 2, 3 ]
    // 2 1 [ 1, 2, 3 ]
    // 3 2 [ 1, 2, 3 ]
});
set.forEach(function (value,samevalue,set) {
    console.log(value,samevalue,set);
    // 1 1 Set { 1, 2, 3 }
    // 2 2 Set { 1, 2, 3 }
    // 3 3 Set { 1, 2, 3 }
});
map.forEach(function (value, key, map) {
    console.log(value,key,map);
    // a 1 Map { 1 => 'a', 2 => 'b', 3 => 'c' }
    // b 2 Map { 1 => 'a', 2 => 'b', 3 => 'c' }
    // c 3 Map { 1 => 'a', 2 => 'b', 3 => 'c' }
});

三.Iterables 和 Iterators

  • 实现了Iterable Protocol的对象,成为可迭代对象,可以使用for…of…进行遍历.自定义的对象也可以实现这一属性,成为可迭代对象。
  • 实现了 Iterator Protocol 的对象称为 迭代器对象,也就是我们说的迭代器对象。

Iterable Protocol : 需要实现一个 ECMA @@iterator 方法,即在键 [Symbol.iterator] 上提供一个方法。对象被 for…of 调用时,这个方法会被调用。方法应该返回一个迭代器对象(Iterator)用来迭代。
iterator Protocol:需要实现一个 next() 方法,每次调用会返回一个包含 value(当前指向的值)和 done(是否已经迭代完成)的对象。

Array的iterable实现方式

首先获取Array的Symbol.iterator属性,

var array = [1,2,3];
var itertor = array[Symbol.iterator]();

然后就可以通过调用迭代器对象的next()方法,进行遍历

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

自定义Iterable对象

我们可以通过实现一个Symbol.iterable成为可迭代对象.

比如实现一个斐波那契数列:

let obj = {
    [Symbol.iterator] () {
        let a = 0,
            b = 0;
        return {
            next () {
                let value = 0;
                if(!a) {
                    value = a = 1;
                }
                else if(!b) {
                    value = b = 1;
                } else if (b < 50) {
                    value = a + b;
                    a = b;
                    b = value;
                }
                return {value, done: value === 0};
            }
        }

    }
}
for(let i of obj) {
    console.log(i);
}

使用Gengerator函数实现:Generator函数直接返回一个Iterator对象.

let obj2 = {
    [Symbol.iterator]: function * () {
        let a = 1,
            b = 1;
        yield a;
        yield b;
        while (b < 50) {
            yield b = a + b;
            a = b - a;
        }
    }
}
for(let i of obj2) {
    console.log(i);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值