An iterator is an object that can access data collections in sequence. One of its typical APIs is the next method. This method obtains the next value in the sequence.
Iterator example
Topic: I hope to write a convenient function that can take any number of parameters and create an iterator for these values.
The test code is good:
var it=values(,,,,,,);it.next();//it.next();//it.next();//it.next();//
Analysis: Since the values function needs to receive any multiple parameters, we need to use the method of building a function with variable parameters mentioned in the previous section. Then the iterator object inside iterates over the elements of the arguments object.
Preliminary code
function values(){var i=,n=arguments.length;return {hasNext:function(){return i<n;},next:function(){if(this.hasNext()){return arguments[i++];}throw new Error("It has reached the end");}}}Test with the above test code
var it=values(,,,,,,);it.next();//undefinedit.next();//undefinedit.next();//undefinedit.next();//undefined
Error analysis
The code running result is not correct, so the initial encoding program will be analyzed below.
function values(){var i=,n=arguments.length;//There is no error here, arguments is the built-in object in values return {hasNext:function(){return i<n;},next:function(){if(this.hasNext()){return arguments[i++];//The error appears here, arguments is the built-in object of the next method function. }throw new Error("It has reached the end");}}}The reference error here is very similar to another headache-inducing object. When dealing with this pointing, it is usually to use variables and save the correct this. Then use this variable elsewhere. Then the solution to the arguments object is released, using a variable to store it, so there is no problem with the reference to the arguments object.
Encoding again
function values(){var i=,n=arguments.length,arg=arguments;return {hasNext:function(){return i<n;},next:function(){if(this.hasNext()){return arg[i++];}throw new Error("It has reached the end");}}}Run the test code
var it=values(,,,,,,);it.next();//it.next();//it.next();//it.next();//
The results are the same as expected.
hint
Beware of function nesting hierarchy when referring to arguments
Bind a explicitly scoped reference to the arguments variable so that it can be referenced in a nested function
Appendix 1: Iterator
Iterators are sometimes called cursors. They are software design patterns for programming, interfaces that can be traversed on containers, and designers do not need to care about the content of containers.
Iterator UML class diagram
Iterator js implementation
I have a little understanding of the design model, but in specific projects, there are many of them that are factory models, which are rarely used. The following is a simple implementation. There is something wrong. Welcome to communicate.
The code is as follows
function List(){this.data=[];}List.prototype={add:function(){var args=[].slice.call(arguments)this.data=this.data.concat(args); },remove:function(i){this.data.splice(i,);},iterator:function(){return new Iterator(this);}}function Iterator(list){this.list=list;this.cur=;};Iterator.prototype={hasNext:function(){return this.cur<this.list.data.length-;},next:function(){if(this.hasNext()){return this.list.data[this.cur++];}throw new Error('It's already over~');},remove:function(){this.list.remove(this.cur);}}var list=new List();var it=list.iterator();list.add(,,,,,,);it.next();//it.next();//it.next();//The above is the method of using variables to save arguments objects in JS introduced to you. I hope it will be helpful to everyone!