Iterator
根据百度百科的说法:
迭代器(Iterator)模式,又叫做游标(Cursor)模式。GOF给出的定义为:提供一种方法访问一个容器(container)对象中各个元素,而又不需暴露该对象的内部细节。 从定义可见,迭代器模式是为容器而生。很明显,对容器对象的访问必然涉及到遍历算法。你可以一股脑的将遍历方法塞到容器对象中去;或者根本不去提供什么遍历算法,让使用容器的人自己去实现去吧。这两种情况好像都能够解决问题。
类似之前的链表结构,每个对象不仅包含自身的值,也包含下一个变量的指针;
function Chan(value){
this.value = value;
this.next = null;
};
var newObj = new Chan(); //对象都有两个属性
创建迭代器
function creatIterator(items){
var i = 0;
var next = function(){
var done =( i>=items.length); //判断itmes的数量是否是最后一个,如果是done = true;那么value = undefined;
var value = !done?items[i++]:undefined; //
return {
value : value,
done : done
};
}
return {next : next};
};
var iterator = new creatIterator([3,3,2,6,7]);
iterator.next() ->{value : 3,done:false;}
iterator.next() ->{value : 3,done:false;}
iterator.next() ->{value : 2,done:false;}
iterator.next() ->{value : 6,done:false;}
iterator.next() ->{value : 7,done:false;}
iterator.next() ->{value :undefined,done:true;} //后面执行的都是一样
//或者省略最后一步;
function creatIterator(items){
var i = 0;
return {
next : function(){
return i<items.length?{
value : array[i++]
}:{
done :true
};
}
}
}
所以可以这样理解,Iterator就是一个特殊的对象,这个对象可以访问一个容器对象(包含很多无序的变量属性等),每次调用next就返回一个对象,直到最后一个,有些方法调用是自动连续的调用,见生成器函数只要有这个接口就可以将返回的对象用扩展运算符...转换为数组并且可以使用数组的方法
有三种数据结构具有原生的Iterator接口,可以直接用for..of 遍历,这三种数结构内置了三个迭代器
entries()返回数组,keys(),values();针对不同的数据结构,都有默认的迭代器,注意不同的浏览器支持的成都不一样;
1,Array
2,Map
3,Set
一些类数组的对象(有数字属性,和length的属性)也具有Iterator 的接口。比如字符串对象
Iterator应用场合
1,解构赋值
var arr = [1,2,3,4,5];
var arr1 = [...arr];
console.dir(arr1) //[1, 2, 3, 4, 5]
2,扩展运算符,同上;
3,特殊场合
//for...of;如果数组有非数字键名的话不可遍历,arr.name = 'obama'
var arr = [1,2,3,4,'a','b'];
var obj = {name : 'obama',1 : 2}
for( pro in arr){console.log(pro)} //0,,,,5只是得到键名;
for( pro in obj){console.log(pro)} //得到所有的属性名
for( pro of o arr){console.log(pro)} //输出所有的属性
for( pro of obj){console.log(pro)} //报错,对象不可遍历
//Array...from;
//Map(),Set()参数对象
//Promise.all(),race()
Generator生成器函数;
有三个属性next,throw,return ;
function *fnName(){ //函数名字前必须有星号;
yield 'first'; //每次执行后都从下一个yield关键字开始,直到最后的return;
yield 'second'; //yield 只能用在生成器函数内部,其他 的会报错
return 'all done';
}
var ob = fnName() //和普通函数一样的调用
ob.next() //
ob.next() //
ob.next() //每次调用都返回一个对象
//每个生成器函数都有Iterator方法并且返回自身
ob[Symbol.iteraro]() === ob;
//1,next()的方法;
//yied和return 一样没有返回值,或者是undefined;
function *fn(){
var num = yield 4;
console.log(num);
}
var s = fn();
s.next(); //{value: 4, done: false}
s.next() //undefined;{value: undefined, done: true};
//next()的参数,可以明确的设定上一次yield的返回值(如果已经是最后的话,就没有作用)
s.next(23); //value : 23,
//生成器函数的遍历for of ... 解构赋值,Array.from都会自动遍历,不需要调用next方法
function *test(){
yield 1;
yield 2;
yield 3;
yield 4;
return 5;
}
var te = test();
for( v of te){console.log(v)} //1,2,3,4
te.next();//{value: undefined, done: true}已经循环完毕
//2,throw方法
//3,return 方法 //直接终止遍历
function *test(){
yield 1;
yield 2;
yield 3;
yield 4;
return 5;
};
var s = test();
s.next();//value:1,done:false;
s.turn ();value:undefined,done:ture; //
s.next();//value:1,done:false;
//yield*语句
function *boo(){
yield 1;
yield 2;
} ;
function *bar(){
yield 3;
yield boo();
}
var s = bar();
s.next();//{value: 3, done: false}
s.next();//{value: boo, done: false}没有执行
//使用yield *boo();表明返回的是一个遍历器对象,可以是数组等其他对象
//{value: 1, done: false}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。