Javascript(笔记36) - ES6特性 - 迭代器


迭代器

迭代器(iterator)是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作。

在JS里,iterator 接口就是对象里的一个属性,这个属性的名字就叫:  Symbol.iterator ;

ES6 创造了一种新的遍历命令 for ... of 循环,iterator 接口主要供 for ... of 消费;

原生具备 intertor 接口的数据(可用于 for ... of 遍历)

Array, Arguments, Set, Map, String, TypeArray, Nodelist 

实例:

const xiyou = ['唐僧','孙悟空','猪八戒','沙和尚'];
for(let v of xiyou){
console.log(v); // 唐僧 孙悟空 猪八戒 沙和尚
}

​for ... of  和  for ... in 的区别​​: 前者输出键值,后者输出键名;

const xiyou = ['唐僧','孙悟空','猪八戒','沙和尚'];
for(let k in xiyou){
console.log(k); // 0 1 2 3
}

为什么说数组可以遍历呢? 是因为数组的原型里有 Symbol.iterator 属性,对应的值是函数;

console.log(Array.prototype);

Javascript(笔记36) - ES6特性 - 迭代器_迭代器

工作原理

1,创建一个指针对象,指向当前数据结构的起始位置;

2,第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员;

3,接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员;

4,每调用 next 方法返回一个包含 value 和 done 属性的对象;

注意:需要自定义遍历数据的时候,可以按这个步骤来做个迭代器;

这个指针对象是什么?

const xiyou = ['唐僧','孙悟空','猪八戒','沙和尚'];
let iterator = xiyou[Symbol.iterator]();
console.log(iterator);

Javascript(笔记36) - ES6特性 - 迭代器_迭代器_02

既然有这个 next 方法,那调用一下看看;

console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());

Javascript(笔记36) - ES6特性 - 迭代器_javascript_03

每调用一次 next 一次,指针会指向下一下成员,直到最后;


迭代器实例

自定义遍历一个试试:

const dalao = {
name:'daj',
member:['my','mht','zym','lqd','wx']
}

for(let v of dalao){
console.log(v); // 报错 dalao is not iterable
}

Javascript(笔记36) - ES6特性 - 迭代器_迭代器_04

类型错误:dalao 对象是不可以迭代的;

当然,这里也可以用 forEach 来遍历:

dalao.member.foEach(item => cosole.log(item));

根据“工作原理”和错误提示,自定义一个迭代器;

const dalao = {
name: 'daj',
member: ['my', 'mht', 'zym', 'lqd', 'wx'],
// 自定义迭代器方法
[Symbol.iterator]() {
// 索引变量
let index = 0;
return {
// 创建 next 方法
next: () => { // 箭头函数保证 this 指向
if (index < this.member.length) {
const result = { value: this.member[index], done: false };
// 下标自增
index ++;
return result;
}else{
return {value: undefined,done:true};
}
}
};
},
}

for (let v of dalao) {
console.log(v); // my mht zym lqd wx
}