迭代器
1.迭代:是从一个数据集合中按照一定的顺序,不断取出数据的过程
2.迭代和遍历的区别?
迭代强调依次取出,不能确定可以取出多少个值,也不能保证把数据取完
遍历必须保证数据的长度,不断地全部取出
3.迭代模式:是一种便臣设计模式,用于统一迭代的过程,并且规范迭代器的格式
4.迭代器:把迭代过程封装起来,(能取出下一个数据,可以判断是否有下一个数据)
js中:如果规定一个对象有next方法,并返回一个对象,就认为这个对象是迭代器
const obj={
next(){
return {
value:data,//数据
done:boolean//判断是否有后续数据
}
}
}
封装一个迭代器
const arr = [1,2,3,4]
function createIterator(arr){
let i = 0
return {
next(){
var result = {
value : arr[i],
done : i >= arr.length
}
i ++;
return result;
}
}
}
const iter = createIterator(arr)
/*
输出结果
iter.next()
{value: 1, done: false}
iter.next()
{value: 2, done: false}
iter.next()
{value: 3, done: false}
iter.next()
{value: 4, done: false}
iter.next()
{value: undefined, done: true}
*/
在es6中如果对象具有知名符号Symbol.iterator,则表示该对象可以迭代
在es6中如果对象具有知名符号属性Symbol.iterator,则表示该对象可以迭代
const iterator = arrSymbol.iterator;//es6之后,数组可以直接创建迭代对象
这里需要注意直接使用数组的方法迭代需要用值接收一下即
const arr = [1, 2, 3, 4]
const iterator = arr[Symbol.iterator]()//能正常输出,
//如直接用arr[Symbol.iterator]().next()则会出现如下问题
//控制台输出内容
/*
iterator.next()
Object { value: 1, done: false }
iterator.next()
Object { value: 2, done: false }
iterator.next()
Object { value: 3, done: false }
iterator.next()
Object { value: 4, done: false }
arr[Symbol.iterator]().next()
Object { value: 1, done: false }
arr[Symbol.iterator]().next()
Object { value: 1, done: false }
arr[Symbol.iterator]().next()
Object { value: 1, done: false }
arr
Array(4) [ 1, 2, 3, 4 ]
大致原因为es6数组迭代方法形成了闭包,演示方法如下
*/
function text() {
let a = Math.random()
return function() {
console.log(a)
}
}
const demo = text()//执行后的text()赋值给demo此时的demo为内部函数体
demo();//0.45445667792917444//因为a随机数已经生成,除再次调用会重新赋值,就不会变化
demo();//0.45445667792917444//所以三个a相等
demo();//0.45445667792917444
text()();//0.6320860615689315//因为每次调用都是执行text()函数后再执行内部函数
text()();//0.004725499087028573//所以a每次值不同
text()();//0.19021527574564823
es6新增for of循环: for of 循环遍历、就是专门针对可迭代对象的,不是可迭代对象不能使用 forof循环(使用方法于for in 一样)
obj对象的原型上没有知名符号属性Symbol.iterator
生成器
生成器既是一个迭代器,同时也是一个可迭代对象
function* test() {//*写在函数名旁边表示这个函数为一个生成器
console.log(123)
yield 1;
console.log(456)
yield 2;
yield 3;
return 4; //return会作为最后的返回对象
}
const generator = test() //生成了一个生成器而已,生成器中的代码并不会执行
// 生成器中关键字 yield 只能在函数内部使用,表示产生一个迭代数据
// 每一次调用生成器中的next方法,会将生成器函数运行到下一个yield关键字的位置
// 如果生成器函数中有多行语句但没有yeild,则next方法全部执行完
// 如果想控制生成器函数中代码输出则可以使用yeild
//使用next方法后会返回一个对象,这个对象就是迭代对象,对象中的value值就是yield后面的值
console.log(generator.next()) //123 Object { value: 1, done: false }
console.log(generator.next())//456 Object { value: 2, done: false }
console.log(generator.next())//789 Object { value: 3, done: false }
console.log(generator.next())//Object { value: 4, done: true }
// 1.生成器有返回值,出现在最后一次的done为true的value
// 2.调用生成器中的next方法时,可以传递参数,传递的参数可以交给yeild表达式的返回值
// 3.第一次去调用函数时,传递的参数是没有任何含义的
function *test(){
let info = yield 1;
console.log(info)
info = yield 2 + info;
console.log(info)
return 10;
}
const generator = test()
//控制台输出
/*
generator.next(9)
Object { value: 1, done: false }
generator.next(9)
9 12.html:15:21
Object { value: 11, done: false }
generator.next(9)
9 12.html:17:21
Object { value: 10, done: true }
*/
生成器api
generator.return() 直接提前结束
generator.throw(new Error(“qwe”))可以在生成器产生一个错误,抛出到对应的行中去