- Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.
directory
Introduction to the iterator pattern
JS traversal
- The value of iterators
ES6 implementation of iterators
–Iterator
Symbol. The iterator attribute
- Implement an iterator generator function
An introduction to the iterator pattern
The iterator pattern provides a way to access the elements of an aggregate object sequentially without exposing the internal representation of the object. Design Patterns: The Foundation of Reusable Object-oriented Software
Iterator pattern, which solves just that one problem — traversal.
Two JS traversal
So often for arrays, objects, arrays of classes, strings, and so forth, we have to use different traversal methods. For example, there are 7 ways to traverse an object, and 10 ways to traverse an array
Such as:
1) for… ofObject cannot be traversed
But you can go through groups of numbers
var obj = {
a:1.b:2
};
for(item of obj){
console.log(item)
}
Copy the code
Obj is not an iterator.
var arr = [11.2.3];
for(item of arr){
console.log(item)
}
/ / 2, 3, 11
Copy the code
So, when we’re iterating over different data types, we need to think about what data types we’re iterating over. Iterators, then, do not need to consider data types and are a more general traversal scheme
See what the definition of an iterator is — while iterating through the collection, we ** don’t care about the internal structure of the collection. And forEach, for, a map… If we want a uniform traversal scheme, we have to come up with a stronger general iterator **
The value of iterators
1) The earliest iterator? – JQ iterators
JQuery we unified the iterator for different types of collections, such as: JQ object collection, DOM object (array) collection, the array collection, way of traversing, to make our every member in the access to collections don’t need to care about the internal structure of the collection itself and set with differences, this is the value of the iterator is ~
fourES6 implementation of iterators
– Iterator
Symbol. The iterator attribute
There are many new features in ES6, including new data structures such as maps and sets. There are now four types of data sets, including arrays and objects. For example, arrays can use forEach, objects can use for… Just as in traverses, should Map and Set be traversed as well? If so, js method object is too much, since the array, object,Map,Set four collections are required to traverse, then can completely use a unified access mechanism. Hence the Iterator.
1) Symbol. The iterator attribute
与 for... of
与 Iterator next method
The ES6 convention states that any data structure that has the symbol. iterator property (which is an implementation of iterator, essentially the default iterator generator for the current data structure) can be iterated over — specifically, by… Next method traversal of and iterators. for… Behind “of” are repeated calls to the “next” method
2) for… ofIn addition to
objectI can go through them all
What’s the reason? Let’s take a look at the prototype array and object instance
In ES6, native data structures LikeArray, Map, Set, String, LikeArray, arguments for functions, and NodeList objects can be accessed via for… Of traverses. The principle is the same. Here we take the simplest array, when we use for… Of traversing the number group:
3) for... of
Through the array
var arr1 = [1.2.3]
var len = arr1.length
for(item of arr1) {
console.log(`${item}`)}Copy the code
4) Why the for… How about “of”?
We are able to retrieve each member of the array one at a time, in order, because we use the array’s symbol. iterator to generate its corresponding iterator object, which is accessed by repeatedly calling the iterator object’s next method
5) Next on the iterator object
, arrSymbol.iterator.next()
var arr1 = [1.2.3]
// Get the iterator object by calling iterator
var iterator1 = arr[Symbol.iterator]()
// Execute next on the iterator object to access the members of the collection one by one
iterator1.next()
iterator1.next()
iterator1.next() // {value: 3, done: false}
iterator1.next() // {value: undefined, done: true}
Copy the code
6) for... of
isIterator loop calls
var arr1=[2.3.5.6]
// Get the iterator object by calling iterator
var iterator1 = arr1[Symbol.iterator]()
// Initializes an iteration result
let now = { done: false }
// Loop outward through the member
while(! now.done) { now = iterator1.next()if(! now.done) {console.log(now.value)
}
}
// 2 3 5 6
Copy the code
Implement an iterator generator function
The iterator generator helps us generate iterator objects. We use generators to generate iterator objects:
1) withES6
theThe generator
Write aIterators generate functions
function *iteratorGenerator() {
yield '100'
yield '200'
yield '300'
}
var iterator = iteratorGenerator()
iterator.next(); // {value: '100', done: false}
iterator.next(); // {value: '200', done: false}
iterator.next(); // {value: '300', done: false}
iterator.next(); // {value: undefined, done: true}
Copy the code
2) useES5
To write one that canGenerate an iterator object
theIterators generate functions
// Define a generator function with an arbitrary set of inputs
function iteratorGenerator(list) {
// idx records the currently accessed index
var idx = 0
// len records the length of the incoming collection
var len = list.length
return {
// Customize the next method
next: function() {
Done is false if the index has not exceeded the collection length
var done = idx >= len
// If done is false, the value can continue
varvalue = ! done ? list[idx++] :undefined
// Return the current value with traversal done
return {
done: done,
value: value
}
}
}
}
var iterator = iteratorGenerator(['100'.'200'.'300'])
iterator.next(); // {value: '100', done: false}
iterator.next(); // {value: '200', done: false}
iterator.next(); // {value: '300', done: false}
iterator.next(); // {value: undefined, done: true}
Copy the code
Here, to keep track of the location of each iteration, we implement a closure that uses free variables as a “cursor” during our iteration.
The iterator pattern is particularly important, so important that languages and frameworks are scrambling to help us implement it. But because of this, there are very few scenarios in your business development that require you to write iterators by hand, so few students will consciously pay attention to the iterator pattern and think about the implementation mechanism behind it.
reference
- 7 ways to traverse an object
- 10 methods of array traversal
- Understand Iterator in ES6
- Iterative agreement
conclusion
Iterator pattern
Provide a methodAccesses elements in an aggregate object sequentially
And youThe internal representation of the object is not exposed
.Iterator pattern
It solves this one problemtraverse
- As we walk through different data types,
We need to think about what data type we're iterating over.
So,Iterators do not care about data types and are a more general traversal scheme
- make
When we access each member of the collection
Don’t careThe internal structure of the collection itself
As well asThe difference between sets
And this isThe value of iterators
- Since this
Arrays, objects, maps, and sets are all traversed
, then completelyA unified access mechanism can be used
. As a resultIterator
Came into being. - ES6 convention, any data structure as long as you have
Symbol. The iterator attribute
(This property isA concrete implementation of Iterator
.It is essentially the default iterator generator for the current data structure
), will doBe traversed
for... of
Right behind itNext method
theRepeated calls
.- for… of
You can iterate over a number
It’s because we useAn array of Symbol. The iterator
To generate theIts corresponding iterator object
Through theCall the next method of the iterator object repeatedly
Accessed an array member Iterators generate functions
Entry participation return
:List - > {}
Iterators generate functions
Object returned
There is aNext method
.Next method
againReturn an object {done:x, value:x}