1.1、认识迭代器迭代器就是通过迭代器调用next方法,让指针指向下一位,从而遍历全部内容。
let names = ['dmc', 'dl', 'dxn', 'dsm', 'djm']
let index = 0
let IteratorObject = {
next() {
if (index < names.length) {
return {
done: false,
value: names[index++]
}
} else {
return {
done: true,
value: undefined
}
}
}
}
console.log(IteratorObject.next())
console.log(IteratorObject.next())
console.log(IteratorObject.next())
console.log(IteratorObject.next())
console.log(IteratorObject.next())
console.log(IteratorObject.next())
console.log(IteratorObject.next())
如上图所示就是一个迭代器,我们通过调用next
函数就可以遍历数组中的所有元素。
1.2、迭代器函数我们可以向迭代器函数中传入一个可迭代对象,这样就得到一个迭代器。
const InteratorFun = function (arr) {
let len = arr.length
let index = 0
return {
next() {
if (index < len) {
return {
done: false,
value: arr[index++]
}
} else {
return {
done: true,
value: undefined
}
}
}
}
}
let arr = ['dmc', 'dl', 'dxn', 'djm', 'csm']
let createArrFun = InteratorFun(arr)
console.log(createArrFun.next())
console.log(createArrFun.next())
console.log(createArrFun.next())
console.log(createArrFun.next())
console.log(createArrFun.next())
console.log(createArrFun.next())
1.3、可迭代对象就是存在[Symbol.iterator]的对象
const num = {
names: ['dmc','dl', 'dxn', 'djm', 'csm'],
[Symbol.iterator]: function() {
let index = 0
return {
next: () => {
if(index < this.names.length) {
return {
done: false,
value: this.names[index++]
}
}else {
return {
done: true,
value: undefined
}
}
}
}
}
}
let inter = num[Symbol.iterator]()
console.log(inter.next())
console.log(inter.next())
console.log(inter.next())
console.log(inter.next())
console.log(inter.next())
console.log(inter.next())
console.log(inter.next())
//此时也可以使用for...of来进行迭代
for(let i of num) {
console.log(i)
}
1.4、内置可迭代对象内置可迭代对象说明内部存在[Symbol.iterator]的对象
//数组
const arr = [1, 2, 3]
for (const item of arr) {
console.log(item)
}
//字符串
const str = '1234567'
for (let i of str) {
console.log(i)
}
//函数中的可迭代对象
function foo() {
for (let item of arguments) {
console.log(item)
}
}
foo('sz', 'sf', 'cs', 'df')
1.5、可迭代对象的应用场景
1、使用for...of可以循环遍历
2、使用解构(指的是数组的解构,对象的解构利用的不是可迭代对象,对象的解构利用的是es9中新增的语法)。
3、展开运算符(数组的展开运算符,es9中新增的对象展开运算符,和迭代器无关)。
4、可以创建新的迭代对象,set类型的数据,其中的参数必须是可迭代对象,如果向其中传入number类型的数据,就会报错。
5、Promise.all()中必须传入可迭代对象。
1.6、自定义可迭代类(一般来说,类是不可以迭代的,但是我们知道一个可迭代对象中一定存在)[Symbol.iterator]()方法, 下面我们自己实现可迭代类。
class ClassRoom {
constructor(name, place, students) {
this.name = name
this.place = place
this.students = students
}
[Symbol.iterator]() {
let index = 0
return {
next: () => {
if (index < this.students.length) {
return {
done: false,
value: this.students[index++]
}
} else {
return {
done: true,
value: undefined
}
}
},
return () { //如果意外终止,则会触发return方法
console.log('意外终止了')
return {
done: true,
value: undefined
}
}
}
}
}
let c1 = new ClassRoom('dl', '计算机2019', ['dmc', 'dxn', 'djm', 'csm'])
for(let i of c1) {
console.log(i)
if(i === 'dxn') {
break
}
}
2.1、生成器函数
1、生成器函数也是函数,只不过生辰器函数存在特殊的样式 function* ()。
2、生成器函数的返回值是一个生成器。
3、生成器函数可以通过yield来控制函数执行流程。
4、生辰器是特殊的迭代器。
2.2、基本使用
function* foo() {
console.log('函数开始执行')
const num1 =100
console.log(num1)
yield
const num2 = 200
console.log(num2)
yield
const num3 = 300
console.log(num3)
yield
console.log('函数执行结束')
}
let generator = foo()
generator.next()
generator.next()
generator.next()
generator.next()
如上述代码所示:返回值generator
是一个生成器,通过不断地调用next
来控制执行流程。
2.3、执行流程
function* foo() {
console.log('函数开始执行')
const num1 =100
console.log(num1)
yield num1 * 100
const num2 = 200
console.log(num2)
yield num2 * 100
const num3 = 300
console.log(num3)
yield num3 * 100
console.log('函数执行结束')
}
let generator = foo()
console.log(generator.next())
console.log(generator.next())
console.log(generator.next())
console.log(generator.next())
console.log(generator.next())
console.log(generator.next())
如上所示,需要执行4步,执行到yield就停止,将yield后面的值作为返回值,格式和迭代器一样。
2.4、生成器函数的next传参
function* foo(num) {
const value1 = 1
const n = yield value1 * 100 * num
const value2 = 10 * n
yield value2 * 200
console.log('函数执行结束.')
}
let generator = foo(100)
console.log(generator.next())
console.log(generator.next(200))
我们可以向生成器的next方法传入参数,其值可以作为yield左边的值。
2.5、生成器函数的return方法
function* foo(num) {
const value1 = 1
const n = yield value1 * 100 * num
const value2 = 10 * n
yield value2 * 200
console.log('函数执行结束.')
}
let generator = foo(100)
console.log(generator.return('哈哈哈哈哈'))
console.log(generator.next(200))
console.log(generator.next(200))
2.6、生成器函数中不仅可以传入参数,也可以抛出异常
function* foo() {
console.log('函数开始执行.')
const value1 = 1
try {
yield value1 * 100
} catch (err) {
console.log(err)
}
const value2 = 10
yield value2 * 200
console.log('函数执行结束.')
}
const generatorFun = foo()
console.log(generatorFun.next())
console.log(generatorFun.throw('这里是错误信息')) //会在第一次执行完,传入值就是报错信息,会被catch捕获到
/**
*在这里报错
* const n = yield value1 * 100
^
*/
2.6、用生成器来代替迭代器
function* createArrInterator(arr) {
yield* arr
}
let interator = createArrInterator(['111', '222', '333'])
console.log(interator.next())
console.log(interator.next())
console.log(interator.next())
console.log(interator.next())
console.log(interator.next())
/**
{ value: '111', done: false }
{ value: '222', done: false }
{ value: '333', done: false }
{ value: undefined, done: true }
{ value: undefined, done: true }
* **/
2.8、用生成器来迭代数字
function* createNumber(a, b) {
while(a < b) {
yield a++
}
}
let num = createNumber(10,20)
console.log(num.next())
console.log(num.next())
console.log(num.next())
console.log(num.next())
console.log(num.next())
console.log(num.next())
console.log(num.next())
console.log(num.next())
console.log(num.next())
console.log(num.next())
console.log(num.next())
2.9、使用生成器来代替迭代器生成class的迭代对象
function* createNumber(a, b) {
while(a < b) {
yield a++
}
}
let num = createNumber(10,20)
console.log(num.next())
console.log(num.next())
console.log(num.next())
console.log(num.next())
console.log(num.next())
console.log(num.next())
console.log(num.next())
console.log(num.next())
console.log(num.next())
console.log(num.next())
console.log(num.next())
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/weixin_47450807/article/details/123418463
内容来源于网络,如有侵权,请联系作者删除!