ForEach = forEach; forEach = forEach; forEach = forEach; forEach = forEach in , for… Of performs traversal differences, and thus introduces and gives a rough introduction to the concept of * iterable/iterator * in ES6.
forEach
The forEach method performs a callback forEach valid value in the array, in ascending order
The characteristics of
- Only “valid values” will be operated on, meaning deleted or uninitialized items will be skipped during traversal, i.e., those with a value of empty will be skipped. Undefined will not be skipped.
forEach
The second argument tothisArg
It can be changed after it is passed incallback
Function of thethis
Value, if not passedundefined
. Of course,callback
To get bythis
Values are also governed by general laws: this means that ifcallback
Is an arrow function, thenthisArg
Will be ignored. (Because the arrow function is already lexically bound to this, it cannot be changed)- It is not recommended to add/delete the contents of the array in the loop: first,
forEach
The traversal scope is called the first timecallback
It will be determined before, which means callforEach
Items added later to the array will not becallback
Access to. At the same time, due toforEach
Traversal is subscription-basedPolyfillSee this implementation in), something strange happens when you delete several items from the array in the loop: for example, in the image below, it is executed at index 1shift()
, so the original third term becomes the second term, and the original second term is skipped.
disadvantages
- Unable to break or break out: If you want to break/break out, consider using the following two methods:
- use
for
/for.. of
- use
Array.prototype.every()
/Array.prototype.some()
And returnfalse
/true
To interrupt/jump out
- use
- Unable to chain call (because returned
undefined
)
for… in
for… The in loop is actually designed for looping enumerable:
for… The IN statement iterates through the enumerable properties of an object in any order. For each different attribute, the statement is executed.
The characteristics of
- Traversing enumerable properties:
for... in
The loop iterates through all the enumerable properties of the object itself, as well as properties that the object inherits from its constructor stereotype (more closely approximating the properties of objects in the stereotype chain overwriting stereotype properties). - Can be interrupted
disadvantages
- It will access all the enumerable attributes of __ that it can access, that is, including those on the stereotype chain. If you want to iterate only over its own attributes, use the
for... in
It also requires coordinationgetOwnPropertyNames()
或hasOwnProperty()
- Can’t guarantee
for ... in
Indexes will be returned in any particular order, such as they might be messed up under IE. - Not recommended for iteration
Array
:- Subscript order is not necessarily guaranteed
- Traversal yields a string of subscripts instead of numbers
for… of
for… The essence of OF is to create an iteration loop by calling its iteration methods on iterable objects and executing the corresponding statement. You can iterate over arrays/strings/typed arrays (TypedArray)/Map/Set/generators/ array-like objects (NodeList/arguments), etc. It is important to note that Object is not an iterable.
for… “Of” is a new addition to ES6, which compensates for forEach and for… Many disadvantages of IN:
- You can use
break
.throw
orreturn
Such termination - Can iterate over arrays properly (depending on the default array iteration behavior)
The difference between
So let’s just say a few words about… Of and the for… The difference between in:
- for… The IN statement iterates over the enumerable properties of an object in the original insertion order (which is not guaranteed).
for... of
Statements traversaliterableDefine the data to iterate over.for... of
I get a value, and I get a valuefor... in
You get a key.
Speaking of iterables, we have to talk about the new iterables/iterators in ES6.
Iterable /The iterator
Iteration * Iteration * is a new iteration mechanism introduced in ES6 that iterates over data. Its core concepts are: iterable and iterator:
- Iterable: * A data structure for internal elements that is intended to be accessed by the outside world, implementing the symbol. iterator method
- * Iterator: * A pointer used to iterate over data structure elements
Iterable Protocol
First, the iterable protocol allows JavaScript objects to define or customize their iterative behavior. Built-in iterables such as Array or Map have the default iterative behavior, while objects do not. (So why not use for Object… Iterator (of), an object or its prototype has a [symbol. iterator] method that returns an object that complies with the iterator protocol. Then, when the object is iterated over, the [symbol.iterator] method is called to obtain an iterator to be used in the iteration.
The first thing you can see is that Array and Map have this method on the prototype chain, while Object does not. This confirms the above for what can be used for… Of.
If we really want to use for… To iterate over properties owned by an Object, use the built-in object.keys () method:
for (const key of Object.keys(someObject)) {
console.log(key + ":" + someObject[key]);
}
Copy the code
Or if you want to make it easier to get both keys and values, consider using Object.entries() :
for (const [key, value] of Object.entries(someObject)) {
console.log(key + ":" + value);
}
Copy the code
Second, the iterative behavior of an iterable is used in the following cases:
for... of
- Spread syntax
- yield*
- Destructuring Assignment
- Some built-in apis for accepting iterables (essentially, these interfaces call the behavior of iterating an array when they receive an array as a parameter)
- Array.from()
- Map(), Set(), WeakMap(), WeakSet()
- Promise. All ()/Promise. Race (), etc
Iterator Protocol
Since an iterator is returned for iteration, let’s take a look at what specifications qualify as an iterator. All you need to do is implement an object with the following next method:
attribute
|
value
|
next
|
A nonparametric function that returns an object with two attributes:
|
Essentially, when using an iterator, its next() method is called repeatedly until it returns done: true.
Custom iteration behavior
Since all iterable objects that conform to the iterable protocol are iterable, let’s simply define the iteration behavior:
// Let our array output value in reverse order
const myArr = [1.2.3];
myArr[Symbol.iterator] = function () {
const that = this;
let index = that.length;
return {
next: function () {
if (index > 0) {
index--;
return {
value: that[index],
done: false
};
} else {
return {
done: true}; }}}; }; [...myArr];/ / [3, 2, 1)
Array.from(myArr) / / [3, 2, 1)
Copy the code
One sentence describes the relationship between an iterable and an iterator
When a __ iterable __ needs to be iterated over, its symbol. iterator method is called without arguments and returns an iterator used to get the value in the iteration. In other words, an object (or its prototype) that has a conforming symbol. iterator interface is an iterator. The object returned by calling this interface is an iterator
Close iterator
As mentioned above, for… “Of” is better than “forEach” because it can be “interrupted”. Of interrupts iteration, essentially interrupts iterator, iterator will be closed after interruption. At this point, we continue to talk about iterator closure.
First, there are two cases of iterator closure:
- Exhaustion: When the call is sustained
next()
Method until returndone: true
, that is, the iterator is closed after normal execution - Closing: Through a call
return()
Method to tell the iterator that it is not going to be called againnext()
methods
When will the iterator’s return method be called:
- First of all,
return()
Is optional only for iterators that have that methodClosable - Secondly, only if there is noExhaustion Should be called when
return()
, such asbreak
.throw
orreturn
Etc.
Finally, the return() method does not have its own requirements. The return() method must conform to the following specifications:
return(x)
You should normally return as{ done: true, value: x }
Returns an error if it is not an object- call
return()
Later,next()
The returned object should also bedone:true
(Is that why there are some iterators infor... of
A reason why a loop is broken and cannot be used again, for exampleGenerator
)
Also, it is important to note that return() is also triggered by calling break, etc., just after the last value of the iterator is received.
function createIterable() {
let done = false;
const iterable = {
[Symbol.iterator]() {
return this;
},
next() {
if(! done) { done =true;
return {
done: false.value: 'a'
};
} else {
return {
done: true.value: undefined}; }},return () {
console.log('return() was called! ');
return {
done: true.value: undefined}; }};return iterable;
}
for (const value of createIterable()) {
console.log(value);
break;
}
Copy the code
Generator (Generator)
Both iterator and iterable
The object returned with the next() method mentioned in the iterator protocol above appears to be exactly the same as the next() method we used in Generator. Indeed, the Generator conforms to both iterable and iterator protocols.
Because the Generator has both the canonical next() (iterator protocol) method and the symbol.iterator (iterable protocol) method, it is both an iterator and an iterable.
Shut-off (closable)
By default, Generator objects are closed. So he used for… If the iteration is interrupted, the original Generator object cannot be iterated again. (Because after calling return(), next() should also return done:true)
Of course, since this is the default, we can make it impossible to close: we can override the return() method on the iterator itself/prototype by wrapping the iterator
class PreventReturn {
constructor(iterator) {
this.iterator = iterator;
}
[Symbol.iterator]() {
return this;
}
next() {
return this.iterator.next();
}
// Override the return method
return (value = undefined) {
return {
done: false, value }; }}Copy the code
More on generators will not be covered in this article, but as a separate article if possible.
reference
- MDN-forEach
- MDN-for… in
- MDN-for… of
- Mdn-delete (Cross-browser prompt)
- MDN- Iterative protocol
- MDN-Generator
- The Iterator and for… Of circulation
- Iterables and iterators