迭代器
迭代器是一个特殊的对象,该对象包含一个next
方法,每次调用next
方法后会返回一个结果对象,结果对象中包含一个value
属性和done
属性。如果一个对象原型上具有Symbol.interator
属性的实现,那么该对象就可以使用for of
进行迭代遍历访问。具有内置迭代对象的数据类型有String
、Array
、Map
、Set
、类数组。
特点:
- 所有对象都有一个
next()
方法 - 每次调用
next
方法,都会返回一个对象,该对象包含value
和done
两个属性,value
属性表示下一个将要返回的值,done
是一个布尔值,用来表示该迭代器是否还有数据可以返回。 - 迭代器还会保存一个内部指针指向当前集合中的值。
let arr = [1,2,3];
function createInterator(arr){
let index= 0;
return{
next:()=>{
return index < arr.length?{
value:arr[index++],
done:false
}:{
value:undefined,
done:true
}
}
}
}
let iterator = createInterator(arr)
console.log("1=====>",iterator.next());
console.log("2=====>",iterator.next());
console.log("3=====>",iterator.next());
console.log("4=====>",iterator.next());
生成器
生成器是一种返回迭代器的函数,通过function
关键字后的星号(*)来表示,函数中会用到新的关键字yield
,星号可以紧跟function
后面,也可以在function
后面加空格
function *createInterator(){
yield 10;
yield 20;
yield 30;
}
let iterator = createInterator();
console.log(iterator.next()); //{value: 10, done: false}
console.log(iterator.next()); //{value: 20, done: false}
console.log(iterator.next()); //{value: 30, done: false}
console.log(iterator.next()); //{value: undefined, done: true}
在这个生成器函数中没有next()
方法,也没有value
和done
属性。因为生成器函数内部实现了迭代器。
yield关键字的特点: 每当执行完一条语句,函数就会自动停止执行
注意:
- yield关键字只能在生成器内部使用,在生成器内部的函数使用也会报错
function show(){
yield 10
}
show() //Uncaught SyntaxError: Unexpected number
function *createInterator(arr){
for(let i = 0;i<arr.length;i++){
return function(){
yield arr[i]
}
}
}
let iterator = createInterator([1,2,3]);
console.log(iterator.next()); //Uncaught SyntaxError: Unexpected identifier
- 生成器支持函数表达式的写法,但是不支持箭头函数
let createIterator = function *( arr ){
for( let i = 0;i< arr.length; i++ ) {
yield arr[i];
}
}
let iterator = createIterator( [ 10, 20, 30 ] );
console.log( iterator.next() ); // { done : false, value : 10 }
console.log( iterator.next() ); // { done : false, value : 20 }
console.log( iterator.next() ); // { done : false, value : 30 }
console.log( iterator.next() ); // { done : true, value : undefined }
//以下方法是错误的
var createIterator = * (arr)=>{
for( let i = 0;i< arr.length; i++ ) {
yield arr[i];
}
}
var *createIterator= (arr)=>{
for( let i = 0;i< arr.length; i++ ) {
yield arr[i];
}
}
迭代器的运用
var dream = {a:2,b:3,c:5};
for(var i of dream){
console.log(i); //dream is not iterable
}
由于dream
是不可迭代的,所以使用for of
循环不能遍历
var dream = {a:2,b:3,c:5};
Object.defineProperty(dream,Symbol.iterator,{
enumerable:false, //枚举
writable:false, //可重写
configurable:true, //可配置
value:function(){
var o= this;
var idx = 0; //索引值
var ks = Object.keys(o);
return {
next:function(){
return{
value:o[ks[idx++]],
done:(idx>ks.length)
}
}
}
}
})
for(var i of dream){
console.log(i); //2 3 5
}