迭代器
迭代器
迭代器是一种对象类型,它提供了一个统一的方式来遍历集合中的元素。
它包含两个必要的方法:next() 和 return()。
next()方法在迭代器内部执行时,返回一个对象,包含两个属性:done和 value,用于描述迭代是否已经结束,以及返回的当前元素值。-
return()方法用于中断迭代器的操作。
// 定义迭代器
function createIterator(items) {
let i = 0;
return {
next: function() {
let done = i >= items.length;
let value = !done ? items[i++] : undefined;
return {
done: done,
value: value
}
}
};
}
const iterator = createIterator([1, 2, 3]);
console.log(iterator.next().value); // 1
console.log(iterator.next().value); // 2
console.log(iterator.next().value); // 3
可迭代对象 and Symbol.iterator属性
可迭代对象实现了 Iterable接口的对象,即可以被迭代器进行迭代消费操作的对象
-
可迭代对象都会暴露一个键名为 Symbol.iterator 的属性
- 该属性的值为迭代器工厂函数,且调用该函数会返回一个`迭代器` * [ Symbol.iterator]() { return { next: function() { let done = i >= items.length; let value = !done ? items[i++] : undefined; return { done: done, value: value } } }; } const array = [1, 2, 3]; const iterator = array[Symbol.iterator](); console.log(iterator.next()); // { value: 1, done: false } console.log(iterator.next()); // { value: 2, done: false } console.log(iterator.next()); // { value: 3, done: false } -
一些内置的可迭代对象
- 字符串 - 数组 - 映射 、 集合 - arguments对象 - NodeList -
实际过程中不需要显示的调用上述
工厂函数,一些原生语言会自动帮我们调用!!!- for - of - 数组结构 - 扩展符 - Array.from() - 创建映射 、集合 - yield* 操作符
all in all
可迭代对象,都会有
Symbol.iterator属性,该属性的值是一个迭代器创建函数,即执行该函数会返回一个可以迭代该对象的迭代器,这个迭代器是个对象,且有next()和return()方法。
生成器
生成器
生成器本质是一种特殊类型的函数,使用function*声明,并且可以在函数体内使用yield关键字来暂停函数的执行并返回一个值。
生成器对象
生成器对象是调用生成器函数产生的返回值。它跟
迭代器对象有异曲同工之妙,它也实现了Iterator接口。但是,与迭代器不同,生成器对象具有更灵活的控制能力。除了使用next()方法来向前执行,还可以使用return()方法来提前终止生成器函数,并返回指定的值。还可以使用throw()方法来在生成器函数内部引发异常。
function* generateValues() {
yield 1;
yield 2;
yield 3;
}
const generator = generateValues();
console.log(generator.next()); // { value: 1, done: false }
console.log(generator.return(4)); // { value: 4, done: true }
yield 关键字 【只能在生成器函数中使用】
yield关键字是用于定义生成器函数的特殊关键字,它可以在函数体内指示函数的执行暂停并返回一个值,同时可以在后续调用生成器对象的next()方法时恢复函数的执行。下面是一个使用yield关键字生成数据的示例:
yield*表达式来在函数体内嵌套另一个可迭代对象。跟其他的一起按顺序迭代!!
function* generateValues() {
yield 1;
yield 2;
yield 3;
yield* [4, 5, 6];
}
const generator = generateValues();
console.log(generator.next()); // { value: 1, done: false }
console.log(generator.next()); // { value: 2, done: false }
console.log(generator.next()); // { value: 3, done: false }
console.log(generator.next()); // { value: 4, done: false }
console.log(generator.next()); // { value: 5, done: false }
console.log(generator.next()); // { value: 6, done: false }
console.log(generator.next()); // { value: undefined, done: true }
可以使用 yield 关键字实现输入和输出:
- 数据的输入: 上一次让生成器函数暂停的 yield 关键字会收到传给
next()方法的第一个参数!!![ 即此时,yield 相当于一个变量来接收参数]
function* generator() {
const a = yield;
yield a * 2;
}
const iterator = generator(); // 使用 next 方法启动生成器函数,并暂停在第一个 yield 语句 iterator.next(); // 将值 3 传递给生成器函数,并恢复执行 const { value } = iterator.next(3); console.log(value); // 6
- **数据的输出:** yiled 后面的值 x ,会出现在调用 next( ) 方法后,返回的对象中 { done : false , value : x }
function* generator() {
yield 'apple';
yield 'orange';
yield 'banana';
}
const iterator = generator();
console.log(iterator.next()); // { value: 'apple', done: false }
console.log(iterator.next()); // { value: 'orange', done: false }
console.log(iterator.next()); // { value: 'banana', done: false }
console.log(iterator.next()); // { value: undefined, done: true }
return() 和 throw()
-
return( )
- 传给 return() 方法的值 x,会出现在调用 return() 方法返回的对象中 { done : ture , value : x}
-
throw( )
- throw() 方法会把一个错误注入到生成器对象中,如果错误被捕获处理了,生成器就不会发生中断, 会继续进行,如果未被处理,生成器函数就会中断进行!!!
- 并且如果处理了,生成器会跳过 此时的yiled ,即会跳过一个值!!!(p204)