JavaScript-ES6(2)之迭代器Iterator

210 阅读3分钟

迭代器

  1. 什么是迭代?

从一个数据集合中按照一定的顺序,不断取出数据的过程

  1. 迭代和遍历的区别?

迭代强调的是依次取出,不能确定取出的有多少,也不能保证把数据全部取完。

  1. 什么是迭代器?

对迭代过程的封装,通常为对象,不同的编程语言中,表现出来的迭代形式不一样。

  1. 何为迭代模式?

一种设计模式,用于同一迭代的过程,并且规范迭代器的规格

  1. JS中如何判断迭代器

在JS中规定,如果一个对象有next方法,并且返回一个对象,就认为这个对象为迭代器

创建迭代器

const obj = {
    next(){   用于得到下一个数据
	    return {
	        value : xxx  是当前属性的值
	        done : xxx   用于判断是否遍历结束,一般为boolean,当 done 为 true 时则遍历结束
	            }
	   }
}

举例说明

const arr = [1,2,3,4,5];

const iterator = {//用于迭代数组的对象
    i : 0,
    next(){
        var result = {
            value : arr[this.i],
            done : this.i >= arr.length
        }
        this.i ++;
        return result;
    }
}
console.log(iterator)

这个得到的object对象就为迭代器 我们看到这个对象中有个next()方法,就是用来取数组中的数据的。

设置一个循环,让迭代器自己取数据

    let data = iterator.next();
	while(!data.done){
		console.log(data.value)
		data = iterator.next();
		}
	console.log("迭代完成")

运行结果为:

在ES6中,数组可以直接创建迭代对象

const iterator = arr[Symbol.iterator]();

举例说明

        const items = ["zero", "one", "two"];
        const it = items[Symbol.iterator]();
        let data = it.next();
        while(!data.done){
            console.log(data.value)
            data = it.next();
        }
        console.log("迭代完成")

运行为:

for ... of

具有iterable类型的集合可以通过新的for ... of循环来遍历。ES6标准引入了新的iterable类型,Array、String、Map和Set都属于iterable类型。

for ... of是最简洁、最直接的遍历数组元素的语法,这个方法避开了for-in循环的所有缺陷。

for ... of和for ... in的区别

  1. 推荐在循环对象属性的时候,使用for...in,在遍历数组的时候的时候使用for...of。
  2. for...in循环出的是key,for...of循环出的是value
  3. for...of是ES6新引入的特性。修复了ES5引入的for...in的不足
  4. for in遍历的是数组的索引(即键名),而for of遍历的是数组元素值。

例如:

let aArray = ['a',123,{a:'1',b:'2'}]
for(let index in aArray){
    console.log(`${aArray[index]}`);//a 123 [object Object]
}
for(var value of aArray){
    console.log(value);//a 123 {a:'1',b:'2'}
}

这样看两个貌似没区别,那么我们往数组中添加一个属性name;
aArray.name = 'demo' 输出为:

可以看到第一个for in把我们刚刚添加的name属性也遍历上去了。 所以说,作用于数组的for-in循环除了遍历数组元素以外,还会遍历自定义属性。
下面用for ... of循环对下面几种数据结构进行迭代
Array: 数组 ( Array ) 和类型数组 ( TypedArray ) 他们是可迭代的。

for (let item of ["zero", "one", "two"]) {
  console.log(item);
}
// zero
// one
// two

String:字符串是可迭代的

for (const c of 'abcd') {
    console.log(c);
}
//a
//b
//c
//d

Map:Map 主要是迭代它们的 entries ,每个 entry 都会被编码为 [key, value] 的项, entries 是以确定的形势进行迭代,其顺序是与添加的顺序相同。

const map = new Map();
map.set(0, "zero");
map.set(1, "one");
 
for (let item of map) {
  console.log(item);
}
// [0, "zero"]
// [1, "one"]

Set:Set 是对其元素进行迭代,迭代的顺序与其添加的顺序相同

const set = new Set();
set.add("zero");
set.add("one");
 
for (let item of set) {
  console.log(item);
}
// zero
// one

注:普通对象不可迭代,普通对象由object创建的,不可迭代。