迭代器(Iterator):它是一种接口,为各种不同的数据结构提供t统一的访问机制。只要部署了Iterater接口,就可以完成遍历操作。
1、for of 循环是ES6创建的新的命令,Iterator接口主要供for...of消费
2、原生具备iterator接口的数据(可以用for...of遍历)有Array, Arguments, Set, Map, String, TypedArray, NodeList 。
for...of 与for...in的区别:for...of遍历得到的是值,for...in得到的是键/索引。
Array数组
const arr = ['a', 'b', 'c']
for (let k of arr) {
console.log(k);
}
输出
a
b
c
Arguments
function fn(){
console.log(arguments);
for(let k of arguments){
console.log(k);
}
}
fn('a','b','c')
结果
[Arguments] { '0': 'a', '1': 'b', '2': 'c' } //Arguments
a
b
c
Set
const set = new Set();
set.add('Monday');
set.add('Tuesday');
set.add('Wednesday');
console.log(set);
for(let s of set){
console.log(s);
}
结果
Set(3) { 'Monday', 'Tuesday', 'Wednesday' }
Monday
Tuesday
Wednesday
Map
const map = new Map([['Monday','周一']]);
map.set('Tuesday','周二');
map.set('Wednesday','周三');
console.log(map);
for(let m of map){
console.log(m);
}
结果
Map(3) { 'Monday' => '周一', 'Tuesday' => '周二', 'Wednesday' => '周三' }
[ 'Monday', '周一' ]
[ 'Tuesday', '周二' ]
[ 'Wednesday', '周三' ]
返回的是一个数组,0索引是键,1索引是值。
Map集合里面返回的值是键值对的形式,但是它也会有索引值,用for...in 返回的就是索引值。
String
const str = 'Monday';
for(let s of str){
console.log(s);
}
结果
M
o
n
d
a
y
TypedArray和NodeList暂时还不会,后面学到了再补充。
迭代器的工作原理
1)创建一个指针对象,指向当前数据结构的起始位置
2)第一次调用对象的next方法,指针自动指向数据结构的第一个成员
3)接下来不断调用next方法,指针一直往后移动,直到指向最后一个成员
4)每调用完next方法都会返回一个包含value和done属性的对象
let iterator = str[Symbol.iterator]();
console.log(iterator.next()); //{ value: 'M', done: false }
如果指针指向空时,不会报错,输出是{ value: undefined, done: true}
迭代器的应用
需要自定义遍历数据的时候(比如对象里面的数据)
使用for...of遍历对象
const frineds = {
name:['小明','小红','小华','小李'],
age:18
}
for(let i of frineds){
console.log(i);
}
结果报错
TypeError: frineds is not iterable
at Object.<anonymous> (f:\Z_practice_python\html\Jquery_test\3-原生Ajax\111.js:26:14)
at Module._compile (node:internal/modules/cjs/loader:1191:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1245:10)
at Module.load (node:internal/modules/cjs/loader:1069:32)
at Function.Module._load (node:internal/modules/cjs/loader:904:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
at node:internal/main/run_main_module:22:47
解决方法:在对象里面加上迭代器
const frineds = {
name: ['小明', '小红', '小华', '小李'],
age: 18,
[Symbol.iterator]() {
let index = 0;
return {
next: () => {
if (index < this.name.length) {
const result = { value: this.name[index], done: false }
//这里index一定要记得自增,不然永远都是第一个值
index++;
return result;
} else {
return { value: undefined, done: true }
}
}
}
}
}
根据迭代器的工作原理写迭代器,1、创建一个指针对象,有一个next方法,每次调用完都会返回一个对象,里面包含value和done属性。其中:index一定要记得自增,还有done在完成后一定要变成true,不然循环无法终止。