1、迭代器是一个每次访问集合序列中一个元素的对象,并跟踪该序列中迭代的当前位置。
JavaScript 提供了许多迭代集合的方法,从简单的for循环到forEach()、map()和filter()。
目的:解决繁重的数据处理(在不去了解对象内部情况的前提下,对对象内部进行操作)
封装一个自己的迭代器,首先暴露一个接口,这个接口负责实例化构造器类 Iterator(array)
function Iterator(array){
var _arrob=new _arr(array);
for(var i=0;i<array.length;i++){
_arrob[i]=array[i];
_arrob.length++;
}
return _arrob;
}
//构造器类
function _arr(array){
//把数组存起来
this.array=array;
this.length=0;
this.index=0;
}
_arr.prototype.cur=function(){
return this.array[this.index]
}
_arr.prototype.pre=function(){
if(--this.index<0){
this.index=this.length-1;
return this.array[this.index];
}else{
return this.array[this.index]
}
}
_arr.prototype.next=function(){
if(++this.index>=this.length){
this.index=0;
return this.array[this.index]
}else{
return this.array[this.index]
}
}
_arr.prototype.compareTo=function(num,type){
var _num=num;
var _arr=[];
if(type==='equal') {
_arr = this.dealeach(function (item) {
if (item == _num) {
return item;
}
})
}else if(type==='bigger') {
_arr = this.dealeach(function (item)
{
if (item > _num) {
return item;
}
})
}
return _arr;
}
_arr.prototype.dealeach=function(fn){
var _arr=this.array;
var _empty=[];
for(var i=0;i<this.length;i++){
var item=fn.call(this,_arr[i],i);
if(typeof item=='undefined'){
}else{
_empty.push(item)
}
}
return _empty;
}
//检测输出
var myob=Iterator([1,2,3,4,5]);
console.log(myob);
console.log(myob.cur());
console.log(myob.pre());
console.log(myob.next());
console.log(myob.next());
console.log(myob.next());
var result=myob.compareTo(3,'equal');
console.log(result)
var result1=myob.compareTo(2,'bigger');
console.log(result1)
输出结果为:
可知构造器Iterator返回的是一个_arr的实例对象。以下是这个实例的属性和方法,属性有index,length,而方法存放在原型对象上,有compareTo(),cur(),pre(),next()以及dealeach();
2、考虑可维护性
判断用户需要使用equal()还是Bigger()方法以及其他,一直用的是if...else...,可以用算法\策略模式
把部分代码修改为
function _arr(array){
//把数组存起来
this.array=array;
this.length=0;
this.index=0;
this.actor={
equal: function() {
return function (item, index) {
console.log(item+" "+index)
if (item == num) {
return item;
}
}
},
bigger:function(){
return function (item, index) {
console.log(item+" "+index)
if (item > num) {
return item;
}
}
}
}
}
//....
_arr.prototype.compareTo=function(num,type){
var _num=num;
return this.dealeach(this.actor[type](_num))
}
给_arr对象添加一个actor属性。在使用compareTo方法的时候,给dealeach传入一个fn。这个fn是
equal: function() {
return function (item, index) {
console.log(+item+" "+index)
if (item == num) {
return item;
}
}
输出结果为:
先看输出的1,0各自代表什么
_arr.prototype.dealeach=function(fn){
var _arr=this.array;
var _empty=[];
for(var i=0;i<this.length;i++){
var item=fn.call(this,_arr[i],i);
if(typeof item=='undefined'){
}else{
_empty.push(item)
}
}
return _empty;
}
其中item=fn.call(this,_arr[i],i),有三个参数。后面两个_arr[i],i即为传入fn的参数,本例即为传入equal的参数
报错:说num 未定义;
解决一:
equal: function(num) {
return function (item, index) {
console.log(+item+" "+index)
if (item == num) {
return item;
}
}
},
解决二:
var self=this;
this.actor={
equal: function(num) {
console.log(this);
console.log(self)
return function (num,item, index) {
console.log(item+" "+index)
if (item == num) {
return item;
}
}.bind(self,num)
},
控制窗口输出:
可知在this.actor的action里面this指向已经改变,则用self先缓存起来。
3、可扩展性
用户自己写的方法,可以在其他New生成的实例化中也可使用,则把方法扩展在prototype上
//把actor属性放在原型上
_arr.prototype.actor={
//......
}
_arr.prototype.extendMyfun=function(fname,fn){
console.log(this)
var self=this;
this.actor[fname]=function(num,item,index){
console.log(this)
console.log(self)
return fn.bind(self,num)
}
}
myob.extendMyfun("small",function(num,item,index){
console.log( num ,item ,index)
if (item <= num) {
return item;
}
})
var result2=myob.compareTo(2,'small');
console.log(result2)
var myob1=Iterator([1,1,3,4,5]);
var result3=myob1.compareTo(2,'small');
console.log(result3)
输出结果