You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 1-js/05-data-types/06-iterable/article.md
+27-32Lines changed: 27 additions & 32 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,13 +1,11 @@
1
+
# Iteriebare
1
2
2
-
# Iterables
3
-
4
-
*Iterable* objects is a generalization of arrays. That's a concept that allows us to make any object useable in a `for..of` loop.
3
+
_Iteriebare_ Objekte sind eine Verallgemeinerung von Arrays. Das Konzept ermöglicht es uns, jedes Objekt in einer `for..of` -Schleife zu verwenden.
5
4
6
5
Of course, Arrays are iterable. But there are many other built-in objects, that are iterable as well. For instance, strings are also iterable.
7
6
8
7
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.
9
8
10
-
11
9
## Symbol.iterator
12
10
13
11
We can easily grasp the concept of iterables by making one of our own.
@@ -19,7 +17,7 @@ Like a `range` object that represents an interval of numbers:
19
17
```js
20
18
let range = {
21
19
from:1,
22
-
to:5
20
+
to:5,
23
21
};
24
22
25
23
// We want the for..of to work:
@@ -28,27 +26,26 @@ let range = {
28
26
29
27
To make the `range` iterable (and thus let `for..of` work) we need to add a method to the object named `Symbol.iterator` (a special built-in symbol just for that).
30
28
31
-
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`.
32
-
2. Onward, `for..of` works *only with that returned object*.
29
+
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`.
30
+
2. Onward, `for..of` works _only with that returned object_.
33
31
3. When `for..of` wants the next value, it calls `next()` on that object.
34
-
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.
32
+
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.
35
33
36
34
Here's the full implementation for `range` with remarks:
37
35
38
36
```js run
39
37
let range = {
40
38
from:1,
41
-
to:5
39
+
to:5,
42
40
};
43
41
44
42
// 1. call to for..of initially calls this
45
-
range[Symbol.iterator] =function() {
46
-
43
+
range[Symbol.iterator] =function () {
47
44
// ...it returns the iterator object:
48
45
// 2. Onward, for..of works only with this iterator, asking it for next values
49
46
return {
50
47
current:this.from,
51
-
last:this.to,
48
+
last:this.to,
52
49
53
50
// 3. next() is called on each iteration by the for..of loop
Now `range[Symbol.iterator]()` returns the `range` object itself: it has the necessary `next()` method and remembers the current iteration progress in `this.current`. Shorter? Yes. And sometimes that's fine too.
103
+
Now `range[Symbol.iterator]()` returns the `range` object itself: it has the necessary `next()` method and remembers the current iteration progress in `this.current`. Shorter? Yes. And sometimes that's fine too.
107
104
108
105
The downside is that now it's impossible to have two `for..of` loops running over the object simultaneously: they'll share the iteration state, because there's only one iterator -- the object itself. But two parallel for-ofs is a rare thing, even in async scenarios.
109
106
@@ -115,17 +112,16 @@ There are no limitations on `next`, it can return more and more values, that's n
115
112
Of course, the `for..of` loop over such an iterable would be endless. But we can always stop it using `break`.
116
113
```
117
114
118
-
119
115
## String is iterable
120
116
121
117
Arrays and strings are most widely used built-in iterables.
122
118
123
119
For a string, `for..of` loops over its characters:
124
120
125
121
```js run
126
-
for (let char of"test") {
122
+
for (let char of'test') {
127
123
// triggers 4 times: once for each character
128
-
alert(char); // t, then e, then s, then t
124
+
alert(char); // t, then e, then s, then t
129
125
}
130
126
```
131
127
@@ -134,7 +130,7 @@ And it works correctly with surrogate pairs!
134
130
```js run
135
131
let str ='𝒳😂';
136
132
for (let char of str) {
137
-
alert(char); // 𝒳, and then 😂
133
+
alert(char); // 𝒳, and then 😂
138
134
}
139
135
```
140
136
@@ -167,8 +163,8 @@ That is rarely needed, but gives us more control over the process than `for..of`
167
163
168
164
There are two official terms that look similar, but are very different. Please make sure you understand them well to avoid the confusion.
169
165
170
-
-*Iterables* are objects that implement the `Symbol.iterator` method, as described above.
171
-
-*Array-likes* are objects that have indexes and `length`, so they look like arrays.
166
+
-_Iterables_ are objects that implement the `Symbol.iterator` method, as described above.
167
+
-_Array-likes_ are objects that have indexes and `length`, so they look like arrays.
172
168
173
169
When we use JavaScript for practical tasks in browser or other environments, we may meet objects that are iterables or array-likes, or both.
174
170
@@ -193,7 +189,7 @@ for (let item of arrayLike) {}
193
189
*/!*
194
190
```
195
191
196
-
Both iterables and array-likes are usually *not arrays*, they don't have `push`, `pop` etc. That's rather inconvenient if we have such an object and want to work with it as with an array. E.g. we would like to work with `range` using array methods. How to achieve that?
192
+
Both iterables and array-likes are usually _not arrays_, they don't have `push`, `pop` etc. That's rather inconvenient if we have such an object and want to work with it as with an array. E.g. we would like to work with `range` using array methods. How to achieve that?
The full syntax for `Array.from` also allows us to provide an optional "mapping" function:
224
+
228
225
```js
229
226
Array.from(obj[, mapFn, thisArg])
230
227
```
@@ -237,7 +234,7 @@ For instance:
237
234
// assuming that range is taken from the example above
238
235
239
236
// square each number
240
-
let arr =Array.from(range, num=> num * num);
237
+
let arr =Array.from(range, (num)=> num * num);
241
238
242
239
alert(arr); // 1,4,9,16,25
243
240
```
@@ -270,7 +267,7 @@ for (let char of str) {
270
267
alert(chars);
271
268
```
272
269
273
-
...But it is shorter.
270
+
...But it is shorter.
274
271
275
272
We can even build surrogate-aware `slice` on it:
276
273
@@ -281,26 +278,24 @@ function slice(str, start, end) {
281
278
282
279
let str ='𝒳😂𩷶';
283
280
284
-
alert(slice(str, 1, 3)); // 😂𩷶
281
+
alert(slice(str, 1, 3)); // 😂𩷶
285
282
286
283
// the native method does not support surrogate pairs
287
-
alert(str.slice(1, 3)); // garbage (two pieces from different surrogate pairs)
284
+
alert(str.slice(1, 3)); // garbage (two pieces from different surrogate pairs)
288
285
```
289
286
290
-
291
287
## Summary
292
288
293
-
Objects that can be used in `for..of` are called *iterable*.
289
+
Objects that can be used in `for..of` are called _iterable_.
294
290
295
291
- Technically, iterables must implement the method named `Symbol.iterator`.
296
-
- The result of `obj[Symbol.iterator]` is called an *iterator*. It handles the further iteration process.
297
-
- An iterator must have the method named `next()` that returns an object `{done: Boolean, value: any}`, here `done:true` denotes the end of the iteration process, otherwise the `value` is the next value.
292
+
- The result of `obj[Symbol.iterator]` is called an _iterator_. It handles the further iteration process.
293
+
- An iterator must have the method named `next()` that returns an object `{done: Boolean, value: any}`, here `done:true` denotes the end of the iteration process, otherwise the `value` is the next value.
298
294
- The `Symbol.iterator` method is called automatically by `for..of`, but we also can do it directly.
299
295
- Built-in iterables like strings or arrays, also implement `Symbol.iterator`.
300
296
- String iterator knows about surrogate pairs.
301
297
302
-
303
-
Objects that have indexed properties and `length` are called *array-like*. Such objects may also have other properties and methods, but lack the built-in methods of arrays.
298
+
Objects that have indexed properties and `length` are called _array-like_. Such objects may also have other properties and methods, but lack the built-in methods of arrays.
304
299
305
300
If we look inside the specification -- we'll see that most built-in methods assume that they work with iterables or array-likes instead of "real" arrays, because that's more abstract.
0 commit comments