1.lterator的使用
- lterator的作用
lterator:遍历器(迭代器)
for ()
[1,2].forEach()
new Set().forEach()
lterator是用来遍历的 - 寻找lterator
console.log(lterator); // lterator is not defined
console.log([1, 2][Symbol.iterator]());//Array Iterator {}
const it = [1, 2][Symbol.iterator]();
console.log(it); //Array Iterator {}
- 使用lterator
const it = [1, 2][Symbol.iterator]();
console.log(it.next()); //{value: 1, done: false}
console.log(it.next()); //{value: 2, done: false}
console.log(it.next()); //{value: undefined, done: true}
console.log(it.next()); //{value: undefined, done: true}
// it 可遍历对象(可迭代对象)
Symbol.iterator()://可遍历对象的生成方法
-
什么是lterator
指的是遍历过程Symbol.iterator (可遍历对象的生成方法) -> it (可遍历对象) -> it.next() -> it.next() -> it.next() ...(直到done为true)
2.lterator解惑
- 为什么需要lterator
遍历数组:for循环和forEach
遍历数组: for in
lterator遍历器是一个统一的遍历方式
console.log([][Symbol.iterator]()); //Array Iterator {}
console.log({}[Symbol.iterator]);//undefined
- 如何更方便的使用lterator
Symbol.iterator->it->next()
我们一般不会直接使用lterator去遍历
for…of
3.for of的用法.html
- 认识for…of
const arr = [1, 2, 3];
const it = arr[Symbol.iterator]();
console.log(it.next()); //{value: 1, done: false}
console.log(it.next()); //{value: 2, done: false}
console.log(it.next()); //{value: 3, done: false}
console.log(it.next()); //{value: undefined, done: true}
let next = it.next();
console.log(next); //{value: undefined, done: true}
while (!next.done) {
console.log(next.value);
next = it.next(); //1,2,3
// console.log(next);//{value: 2, done: false} {value: 3, done: false} {value: undefined, done: true}
}
for…of
const arr = [1, 2, 3];
for (const item of arr) {
console.log(item); //1,2,3
}
- 与break、continue一起使用
const arr = [1, 2, 3];
for (const item of arr) {
if (item === 2) {
// break; //1
continue; //1 , 3
}
console.log(item);
}
- 在for…of中取得数组的索引,可以遍历索引值
const arr = [1, 2, 3];
console.log(arr.keys()); //Array Iterator {}
for (const key of arr.keys()) {
console.log(key); //0,1,2
}
// values得到的是值的可遍历对象,可以遍历出值
for (const key of arr.values()) {
console.log(key); //1,2,3
}
for (const key of arr) {
console.log(key); //1,2,3
}
// entries 得到的是索引+值组成的数组的可遍历对象
for (const entries of arr.entries()) {
console.log(entries); // (2) [0, 1] ,(2) [1, 2] ,(2) [2, 3]
}
for (const [index, value] of arr.entries()) {
// console.log(index); // 0,1,2
console.log(value); // 1,2,3
}
4.原生可遍历和非原生可遍历
- 什么是可遍历
只要有Symbol.iterator方法,并且这个方法可以生成可遍历对象,就是可遍历的
只要是可遍历,就可以使用for…of循环来统一遍历 - 原生可遍历的有哪些
数组
字符串
Set
Map
arguments
NodeList
for (const item of[1, 2, 3]) {
console.log(item); //1 2 3
}
for (const item of 'hi') {
console.log(item); //h i
}
for (const item of new Set([1, 2, 3])) {
console.log(item); //1 2 3
}
for (const elem of document.querySelectorAll('p')) {
console.log(elem); // <p>1</p> <p>2</p> <p>3</p>
elem.style.color = 'red';
}
- 非原生的对象有哪些
一般的对象
const person = {
sex: 'ajax',
age: 18
}
// console.log(person[Symbol.iterator]()); //person[Symbol.iterator] is not a function
// 手动添加Symol.iterator
person[Symbol.iterator] = () => {
let index = 0;
return {
next() {
index++;
if (index === 1) {
return {
value: person.age,
done: false
}
} else if (index === 2) {
return {
value: person.sex,
done: false
}
} else {
return {
done: true
}
}
}
}
}
for (const item of person) {
console.log(item); //18 ajax
}
for in
有length和索引属性的对象
const obj = {
0: 'ajax',
1: 'male',
length: 2
}
// 1.
obj[Symbol.iterator] = Array.prototype[Symbol.iterator];
// 2.
obj[Symbol.iterator] = () => {
let index = 0;
return {
next() {
let value, done;
if (index < obj.length) {
value = obj[index];
done = false;
} else {
value = undefined;
done = true;
}
index++;
return {
value,
done
}
}
}
}
for (const item of obj) {
console.log(item); //ajax male
}
5.使用lterator的场合
- 使用lterator的场合
Array数组
String字符串
Set
Map
函数的arguments对象
NodeList对象
for of - 数组的展开运算符
console.log(...[1, 2, 3]); //1 2 3
console.log(1, 2, 3);//1 2 3
console.log(...'str'); //s t r
console.log(...new Set([1, 2, 3])); //1 2 3
console.log(... {}); //报错
- .数组的解构赋值
const [a, b] = [1, 2]; //1 2
const [a, b] = [...[1, 2]]; //1 2
const [a, b] = 'hi'; //h i
const [a, b] = [...'hi']; //h i
const [a, b] = [...new Set([2, 3])]; //2 3
console.log(a, b);
- Set和Map的构造函数
new Set(iteartor)
new Map(iteartor)
6.小结
- Iterator 遍历器
Iterator 是统一的遍历方式
Symbol.iterator(可遍历对象的生成方法)-> it(可遍历对象)
-> it.next() -> it.next() -> …(直到 done 为 true 停止遍历)
一般不直接使用 Iterator,而是通过 for…of 循环间接使用 - for…of 循环
for…of 循环内部使用了 Iterator
for…of 循环可以与 break、continue 一起使用
在 for…of 中可以通过 keys() 或 entries() 取得数组的索引 - 可遍历
只要有 Symbol.iterator 方法,并且这个方法可以生成
可遍历对象,就是可遍历的
只要可遍历,就可以使用 for…of 循环来统一遍历
数组、字符串、Set、Map、arguments、NodeList
是原生可遍历的
一般的对象不是原生可遍历的 - 使用了 Iterator 的场合
数组的展开运算符使用了 Iterator
数组的解构赋值使用了 Iterator
Set 和 Map 的构造函数使用了 Iterator