fixes
This commit is contained in:
parent
bbf98b2ef0
commit
5ecfdf625e
1 changed files with 8 additions and 10 deletions
|
@ -3,9 +3,9 @@
|
|||
|
||||
*Iterable* objects is a generalization of arrays. That's a concept that allows to make any object useable in a `for..of` loop.
|
||||
|
||||
Of course, Arrays are iterable. But there are many other built-in objects, that are iterable as well. For instance, Strings are iterable also. As we'll see, many built-in operators and methods rely on them.
|
||||
Of course, Arrays are iterable. But there are many other built-in objects, that are iterable as well. For instance, strings are also iterable.
|
||||
|
||||
If an object represents a collection (list, set) of something, then `for..of` is a great syntax to loop over it, so let's see how to make it work.
|
||||
If an object isn't technically an array, but represents a collection (list, set) of something, then `for..of` is a great syntax to loop over it, so let's see how to make it work.
|
||||
|
||||
|
||||
## Symbol.iterator
|
||||
|
@ -31,9 +31,9 @@ To make the `range` iterable (and thus let `for..of` work) we need to add a meth
|
|||
1. When `for..of` starts, it calls that method once (or errors if not found). The method must return an *iterator* -- an object with the method `next`.
|
||||
2. Onward, `for..of` works *only with that returned object*.
|
||||
3. When `for..of` wants the next value, it calls `next()` on that object.
|
||||
4. The result of `next()` must have the form `{done: Boolean, value: any}`, where `done=true` means that the iteration is finished, otherwise `value` must be the new value.
|
||||
4. The result of `next()` must have the form `{done: Boolean, value: any}`, where `done=true` means that the iteration is finished, otherwise `value` is the next value.
|
||||
|
||||
Here's the full implementation for `range`:
|
||||
Here's the full implementation for `range` with remarks:
|
||||
|
||||
```js run
|
||||
let range = {
|
||||
|
@ -68,10 +68,10 @@ for (let num of range) {
|
|||
}
|
||||
```
|
||||
|
||||
Please note the core feature of iterables: an important separation of concerns:
|
||||
Please note the core feature of iterables: separation of concerns.
|
||||
|
||||
- The `range` itself does not have the `next()` method.
|
||||
- Instead, another object, a so-called "iterator" is created by the call to `range[Symbol.iterator]()`, and it handles the whole iteration.
|
||||
- Instead, another object, a so-called "iterator" is created by the call to `range[Symbol.iterator]()`, and its `next()` generates values for the iteration.
|
||||
|
||||
So, the iterator object is separate from the object it iterates over.
|
||||
|
||||
|
@ -140,9 +140,7 @@ for (let char of str) {
|
|||
|
||||
## Calling an iterator explicitly
|
||||
|
||||
Normally, internals of iterables are hidden from the external code. There's a `for..of` loop, that works, that's all it needs to know.
|
||||
|
||||
But to understand things a little bit deeper let's see how to create an iterator explicitly.
|
||||
For deeper understanding let's see how to use an iterator explicitly.
|
||||
|
||||
We'll iterate over a string in exactlly the same way as `for..of`, but with direct calls. This code creates a string iterator and gets values from it "manually":
|
||||
|
||||
|
@ -283,7 +281,7 @@ let str = '𝒳😂𩷶';
|
|||
|
||||
alert( slice(str, 1, 3) ); // 😂𩷶
|
||||
|
||||
// native method does not support surrogate pairs
|
||||
// the native method does not support surrogate pairs
|
||||
alert( str.slice(1, 3) ); // garbage (two pieces from different surrogate pairs)
|
||||
```
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue