preface
JavaScript provides four types of data sets: array, Object, Map, and set. The data structures of these four data sets are different, but they can all be iterated over. This is supported by iteration(iterator). An Iterator is a mechanism, or interface, that provides a unified access mechanism for a variety of different data structures. Any data structure configured with the Iterator interface can be iterated through (that is, processing all the members of the data structure in turn)
1. What is iteration
Iteration is called an iterator, also called a traverser. Its function is to provide a unified traversal access mechanism for different data structures. This mechanism can make the members of the data structure be traversed and accessed in sequence. The most common traversal is array and map. Such as
const arr=['a'.'b'.'c'];
for (let i of arr){
console.log(i)
//a, b, c
}
const map=new Map([[1.'x'], [2.'y'], [3.'z']]);
for (let j of map){
console.log(j)
//[1, 'x'], [2, 'y'], [3, 'z']
}
Copy the code
You should be curious if this isn’t the for for array and map data… What does this have to do with iteration? If you have this question, you don’t know much about Iteration and should read this article. Actually, for… Iteration is called behind the of loop. In other words, because iteration is deployed on the array object, the array is an iterable, so it can be called by the iteration property for… Of traversal, which will be covered later in this article. From the above example we get two pieces of information:
- Array, map data structure can use for… Of traversal
- The traversal process is based on a specific order of elements, the preceding elements are traversed first
Iteration does three things:
- To provide a unified and simple access interface for various data structures;
- To enable the members of a data structure to be arranged in some order;
- Mainly used for
for... of
consumption
What does iteration work on? Instead, iteration iterates into a pointer object that points to the starting position of the current data structure. That is, the traverser object is essentially a pointer object. This object has a next method inside it, which is then called to move the pointer to point to the first element in the data structure. Each time the next method is called, the pointer points to the next element in the data structure, so that repeated calls to the next method can iterate over the elements! In addition, each time the next method is called, information about the current member of the data structure is returned. Specifically, it returns an object containing both the value and done attributes. The value attribute is the value of the current member, and the done attribute is a Boolean value indicating whether the traversal is complete. Based on how iteration works, we can create one by hand. Handwritten iteration simply returns a pointer object that points to the starting position of the data. Inside the object should be the next method, which returns an object with the value and done properties. So let’s implement it:
function myIteration(arr){
var index=0;
return {
next:function(){
return index<arr.length ?
{value:arr[index++],done:false}:
{value:undefined.done:true}}}}var test=myIteration([1.2])
console.log(test.next()) //{ "value": 1, "done": false }
console.log(test.next()) //{ "value": 2, "done": false }
console.log(test.next()) //{ "value": undefined, "done": true }
Copy the code
In this code, myIteration is an iterator generator function that returns an iterator object with a next method. Then call the next function on the object to iterate through the array through the internal index index. Similarly, if arr is not an array but a map or set object, then we can implement map and set iterators! Iteration therefore provides a unified access mechanism for various data structures.
2. Native and custom Iteration interfaces
We don’t write myIteration when iterating through arrays in JS, because js already has this interface built into arrays. When we use for… When the of loop iterates over a set of data structures, the loop automatically looks for the Iterator interface and executes the loop. A data structure is said to be “iterable” whenever the Iterator interface is deployed. So we can transform the original non-traversable data into traversal data.
ES6 specifies that the default Iterator interface is deployed in the symbol. Iterator property of the data structure. The symbol. Iterator property is itself a function, which is the default Iterator generator of the current data structure. Executing this function returns a traverser object with the next method. Iterator is an expression that returns the iterator property of the Symbol object, which is a predefined special value of type Symbol, so it is enclosed in square brackets.
The data structure with Iterator interface in JS is as follows:
- Array
- Map
- Set
- String
- TypedArray
- The arguments object for the function
- The NodeList object
Therefore, any of the above data types support for… Iteration can also call its own symbol. Iteration method, for example 🌰 :
let arr = ['a'.'b'.'c'];
// Call the native symbol. iterator method to return an iterator object
let iter = arr[Symbol.iterator]();
// Call the next method on the traverser to return an information object representing the current member
iter.next() // { value: 'a', done: false }
iter.next() // { value: 'b', done: false }
iter.next() // { value: 'c', done: false }
iter.next() // { value: undefined, done: true }
Copy the code
Of course, we can also change non-iterable data types to be iterable to support for… Of loops, such as objct! If we execute for… directly on the object Of is bound to be wrong:
let obj={
'name':'Fawn in front'.'age':'18'.'sex':'male'
}
for (let i of obj){
console.log(i) //obj is not iterable,obj is not iterable
}
// Modify obj
let obj={
data: ['Name: Front fawn'.'age:18'.'sex: male'],
[Symbol.iterator]:function(){
const self=this
let index=0;
return {
next:function(){
if (index < self.data.length) {
return {
value: self.data[index++],
done: false
};
}
return { value: undefined.done: true}; }}}}for (let i of obj){
console.log(i)
//"name:前端小鹿" "age:18" "sex:男"
}
Copy the code
Wuhu ~ take off. By using the principle of iteration, we transform the object into an iterable and successfully use for… Of implements the loop, nice!
For array-like objects, it is much easier to modify them. We can simply refer to the Iterator interface of the array directly. For example, 🌰 :
let iterable = {
0: 'a'.1: 'b'.2: 'c'.length: 3[Symbol.iterator]: Array.prototype[Symbol.iterator]
};
for (let item of iterable) {
console.log(item); // 'a', 'b', 'c'
}
Copy the code
Note that this method of referring directly to the Iterator interface only applies to objects like arrays. This method does not apply to ordinary objects. Use the Symbol.
3. When will the Iteration interface be used
We have already introduced… Of uses the Symbol. Iterator method, as well as other situations.
- Deconstruction assignment
The symbol. iterator method is called by default when destructuring arrays and Set structures.
let set = new Set().add('a').add('b').add('c');
let [first, ...rest] = set;
// first='a'; rest=['b','c'];
Copy the code
- Extended operators (…)
var str = 'hello'; STR [...] / [' h ', 'e', 'l', 'l', 'o'], string on the iteration, so the string can also be used for... Let arr = ['b', 'c']; ['a', ...arr, 'd'] // ['a', 'b', 'c', 'd']Copy the code
- Generator After a generator function is called, the function does not execute and instead of returning the result of the function’s operation, it returns a traverser object
let myIterable = { [Symbol.iterator]: function* () { yield 'a'; yield 'b'; yield 'c'; }}; console.log([...myIterable]) // [a, b, c] for (let i of myIterable){ console.log(i) // [a, b, c] }Copy the code
There are other methods that use iteration behind them, such as array.from (), promise.all (), etc., which are not described here.
4, summarize
In general, a data structure that deploys the Symbol. Iterator attribute is considered to have an iterator interface. Of circulates consumption, thus iterating through its members. We understand the principle of Iteration to make better use of the data structures provided by JS and, if necessary, to modify non-iterative data structures.