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
*Iterable* objects is a generalization of arrays. That's a concept that allows us to make any object useable in a `for..of` loop.
4
+
Los objetos *iterables* son una generalización de matrices. Este es un concepto que permite que cualquier objeto pueda ser utilizado en un blucle `for..of`.
5
5
6
-
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
-
8
-
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.
6
+
Por supuesto, las matrices o *arrays* son iterables. Pero hay muchos otros objetos integrados, que también lo son. Por ejemplo, las cadenas o *strings* son iterables también. Como veremos, muchos operadores y métodos se basan en la iterabilidad.
9
7
8
+
Si un objeto no es técnicamente una matriz, pero representa una colección (lista, conjunto) de algo, entonces el uso de la sintaxis `for..of` es una gran forma de recorrerlo, así que veamos cómo funciona.
10
9
11
10
## Symbol.iterator
12
11
13
-
We can easily grasp the concept of iterables by making one of our own.
12
+
Podemos comprender fácilmente el concepto de iterables por medio de la práctica.
13
+
14
+
Por ejemplo, tenemos un objeto, que no es una matriz, pero parece adecuado para `for..of`.
14
15
15
-
For instance, we have an object that is not an array, but looks suitable for `for..of`.
16
16
17
-
Like a `range`object that represents an interval of numbers:
17
+
Como un objeto `range`que representa un intervalo de números:
18
18
19
19
```js
20
20
let range = {
21
21
from:1,
22
22
to:5
23
23
};
24
24
25
-
//We want the for..of to work:
25
+
//Queremos que el for..of funcione de la siguiente manera:
26
26
// for(let num of range) ... num=1,2,3,4,5
27
27
```
28
28
29
-
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
-
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*.
33
-
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.
29
+
Para hacer que el `range` sea iterable (y así permitir que `for..of` funcione) necesitamos agregar un método al objeto llamado `Symbol.iterator` (un símbolo incorporado especial usado solo para realizar esa función, proporcionar iterabilidad).
35
30
36
-
Here's the full implementation for `range` with remarks:
31
+
1. Cuando se inicia el `for..of`, éste llama al método `Symbol.iterator` una vez (o genera un error si no lo encuentra). El método debe devolver un *iterador* --un objeto con el método `next()`.
32
+
2. En adelante, `for..of` trabaja *solo con ese objeto devuelto*.
33
+
3. Cuando `for..of` quiere el siguiente valor, llama a `next()` en ese objeto.
34
+
4.El resultado de `next()` debe tener la forma `{done: Boolean, value: any}`, donde `done = true` significa que la iteración ha finalizado; de lo contrario,`value` debe ser el nuevo valor.
37
35
36
+
Aquí está la implementación completa de `range`:
37
+
38
38
```js run
39
39
let range = {
40
40
from:1,
41
41
to:5
42
42
};
43
43
44
-
// 1. call to for..of initially calls this
44
+
// 1. Una llamada a for..of inicializa una llamada a esto:
45
45
range[Symbol.iterator] =function() {
46
46
47
-
// ...it returns the iterator object:
48
-
// 2. Onward, for..of works only with this iterator, asking it for next values
47
+
// ... devuelve el objeto iterador:
48
+
// 2. En adelante, for..of trabaja solo con este iterador, pidiéndole los siguientes valores
49
49
return {
50
50
current:this.from,
51
51
last:this.to,
52
52
53
-
// 3. next() is called on each iteration by the for..of loop
53
+
// 3. next() es llamado en cada iteración por el bucle for..of
54
54
next() {
55
-
// 4. it should return the value as an object {done:.., value :...}
55
+
// 4. debería devolver el valor como un objeto {done:.., value :...}
Please note the core feature of iterables: separation of concerns.
71
+
Tenga en cuenta la característica principal de los iterables: separación de conceptos.
72
72
73
-
-The`range`itself does not have the `next()` method.
74
-
-Instead, another object, a so-called "iterator" is created by the call to `range[Symbol.iterator]()`, and its`next()`generates values for the iteration.
73
+
-El`range`en sí mismo no tiene el método `next()`.
74
+
-En cambio, la llamada a `range[Symbol.iterator]()` crea un otro objeto llamado "iterador", y su`next()`genera valores para la iteración.
75
75
76
-
So, the iterator object is separate from the object it iterates over.
76
+
Por lo tanto, el objeto iterador está separado del objeto sobre el que itera.
77
77
78
-
Technically, we may merge them and use `range`itself as the iterator to make the code simpler.
78
+
Técnicamente, podemos fusionarlos y usar `range`en sí mismo como iterador para simplificar el código.
79
79
80
-
Like this:
80
+
De esta manera:
81
81
82
82
```js run
83
83
let range = {
@@ -103,51 +103,51 @@ for (let num of range) {
103
103
}
104
104
```
105
105
106
-
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.
106
+
Ahora`range[Symbol.iterator]()`devuelve el objeto `range`en sí: tiene el método `next()`necesario y recuerda el progreso de iteración actual en `this.current`. ¿Más corto? Sí. Y a veces eso también está bien.
107
107
108
-
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.
108
+
La desventaja es que ahora es imposible tener dos bucles `for..of` corriendo sobre el objeto simultáneamente: compartirán el estado de iteración, porque solo hay un iterador: el objeto en sí. Pero dos for-ofs paralelos es algo raro, incluso en escenarios asíncronos.
109
+
110
+
```smart header="Iteradores Infinitos"
111
+
También son posibles los iteradores infinitos. Por ejemplo, el objeto `range` se vuelve infinito así: `range.to = Infinity`. O podemos hacer un objeto iterable que genere una secuencia infinita de números pseudoaleatorios. También puede ser útil.
109
112
110
-
```smart header="Infinite iterators"
111
-
Infinite iterators are also possible. For instance, the `range` becomes infinite for `range.to = Infinity`. Or we can make an iterable object that generates an infinite sequence of pseudorandom numbers. Also can be useful.
113
+
No hay limitaciones en `next`, puede devolver más y más valores, eso es normal.
112
114
113
-
There are no limitations on `next`, it can return more and more values, that's normal.
114
-
115
-
Of course, the `for..of` loop over such an iterable would be endless. But we can always stop it using `break`.
115
+
Por supuesto, el bucle `for..of` sobre un iterable de este tipo sería interminable. Pero siempre podemos detenerlo usando `break`.
116
116
```
117
117
118
+
## *String* es iterable
118
119
119
-
## String is iterable
120
-
121
-
Arrays and strings are most widely used built-in iterables.
120
+
Las matrices y cadenas son los iterables integrados más utilizados.
122
121
123
-
For a string, `for..of`loops over its characters:
122
+
En una cadena o *string*, el bucle `for..of`recorre sus caracteres:
124
123
125
124
```js run
126
125
for (let char of"test") {
127
-
//triggers 4 times: once for each character
128
-
alert( char ); // t, then e, then s, then t
126
+
//Se dispara 4 veces: una vez por cada caracter
127
+
alert( char ); // t, luego e, luego s, luego t
129
128
}
130
129
```
131
130
132
-
And it works correctly with surrogate pairs!
131
+
¡Y trabaja correctamente con valores de pares sustitutos (codificación UTF-16)!
133
132
134
133
```js run
135
134
let str ='𝒳😂';
136
135
for (let char of str) {
137
-
alert( char ); // 𝒳, and then 😂
136
+
alert( char ); // 𝒳, y luego 😂
138
137
}
139
138
```
140
139
141
-
## Calling an iterator explicitly
140
+
## Llamar a un iterador explícitamente
142
141
143
-
For deeper understanding let's see how to use an iterator explicitly.
142
+
Para una comprensión más profunda, veamos cómo usar un iterador explícitamente.
144
143
145
-
We'll iterate over a string in exactly the same way as `for..of`, but with direct calls. This code creates a string iterator and gets values from it "manually":
144
+
Vamos a iterar sobre una cadena exactamente de la misma manera que `for..of`, pero con llamadas directas. Este código crea un iterador de cadena y obtiene valores de él "manualmente":
146
145
146
+
147
147
```js run
148
-
let str ="Hello";
148
+
let str ="Hola";
149
149
150
-
//does the same as
150
+
//hace lo mismo que
151
151
// for (let char of str) alert(char);
152
152
153
153
*!*
@@ -157,92 +157,93 @@ let iterator = str[Symbol.iterator]();
157
157
while (true) {
158
158
let result =iterator.next();
159
159
if (result.done) break;
160
-
alert(result.value); //outputs characters one by one
160
+
alert(result.value); //retorna los caracteres uno por uno
161
161
}
162
162
```
163
+
Rara vez se necesita esto, pero nos da más control sobre el proceso que `for..of`. Por ejemplo, podemos dividir el proceso de iteración: iterar un poco, luego parar, hacer otra cosa y luego continuar.
164
+
165
+
## Iterables y array-likes [#array-like]
163
166
164
-
That is rarely needed, but gives us more control over the process than `for..of`. For instance, we can split the iteration process: iterate a bit, then stop, do something else, and then resume later.
167
+
Hay dos términos oficiales que se parecen, pero son muy diferentes. Asegúrese de comprenderlos bien para evitar confusiones.
168
+
169
+
-*Iterables* son objetos que implementan el método `Symbol.iterator`, como se describió anteriormente.
170
+
-*Array-likes* son objetos que tienen índices y `longitud` o *length*, por lo que se ven como matrices.
165
171
166
-
## Iterables and array-likes [#array-like]
172
+
Cuando usamos JavaScript para tareas prácticas en el navegador u otros entornos, podemos encontrar objetos que son iterables o array-like, o ambos.
167
173
168
-
There are two official terms that look similar, but are very different. Please make sure you understand them well to avoid the confusion.
174
+
Por ejemplo, las cadenas son iterables (`for..of` funciona en ellas) y array-like (tienen índices numéricos y `length`).
169
175
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.
176
+
Pero un iterable puede no ser array-like. Y viceversa, un array-like puede no ser iterable.
172
177
173
-
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
178
175
-
For instance, strings are both iterable (`for..of` works on them) and array-like (they have numeric indexes and `length`).
179
+
Por ejemplo, `range` en el ejemplo anterior es iterable, pero no array-like, porque no tiene propiedades indexadas ni `longitud` o *length*.
176
180
177
-
But an iterable may be not array-like. And vice versa an array-like may be not iterable.
178
181
179
-
For example, the `range` in the example above is iterable, but not array-like, because it does not have indexed properties and `length`.
180
-
181
-
And here's the object that is array-like, but not iterable:
182
+
Y aquí está el objeto que tiene forma de matriz, pero no es iterable:
182
183
183
184
```js run
184
-
let arrayLike = { //has indexes and length => array-like
185
-
0:"Hello",
186
-
1:"World",
185
+
let arrayLike = { //tiene índices y longitud => array-like
186
+
0:"Hola",
187
+
1:"Mundo",
187
188
length:2
188
189
};
189
190
190
191
*!*
191
-
// Error (no Symbol.iterator)
192
+
// Error (sin Symbol.iterator)
192
193
for (let item of arrayLike) {}
193
194
*/!*
194
195
```
195
196
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?
197
+
Tanto los iterables como los array-like generalmente no son *matrices*, no tienen "push", "pop", etc. Eso es bastante inconveniente si tenemos un objeto de este tipo y queremos trabajar con él como con una matriz. P.ej. nos gustaría trabajar con `range`utilizando métodos de matriz. ¿Cómo lograr eso?
197
198
198
199
## Array.from
199
200
200
-
There's a universal method [Array.from](mdn:js/Array/from)that takes an iterable or array-like value and makes a "real" `Array`from it. Then we can call array methods on it.
201
+
Existe un método universal [Array.from](https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/Array/from)que toma un valor iterable o similar a una matriz y crea un `Array`¨real¨ a partir de él. De esta manera podemos llamar y usar métodos que pertenecen a una matriz.
201
202
202
-
For instance:
203
+
Por ejemplo:
203
204
204
205
```js run
205
206
let arrayLike = {
206
-
0:"Hello",
207
-
1:"World",
207
+
0:"Hola",
208
+
1:"Mundo",
208
209
length:2
209
210
};
210
211
211
212
*!*
212
213
let arr =Array.from(arrayLike); // (*)
213
214
*/!*
214
-
alert(arr.pop()); //World (method works)
215
+
alert(arr.pop()); //Mundo (el método pop funciona)
215
216
```
216
217
217
-
`Array.from`at the line`(*)`takes the object, examines it for being an iterable or array-like, then makes a new array and copies all items to it.
218
+
`Array.from`en la línea`(*)`toma el objeto, lo examina por ser iterable o similar a una matriz, luego crea una nueva matriz y copia allí todos los elementos.
218
219
219
-
The same happens for an iterable:
220
+
Lo mismo sucede para un iterable:
220
221
221
222
```js
222
-
//assuming that range is taken from the example above
223
+
//suponiendo que range se toma del ejemplo anterior
alert(arr); // 1,2,3,4,5 (la conversión de matriz a cadena funciona)
225
226
```
226
227
227
-
The full syntax for`Array.from`also allows us to provide an optional "mapping" function:
228
+
La sintaxis completa para`Array.from`también nos permite proporcionar una función opcional de "mapeo":
228
229
```js
229
230
Array.from(obj[, mapFn, thisArg])
230
231
```
231
232
232
-
The optional second argument`mapFn`can be a function that will be applied to each element before adding it to the array, and`thisArg`allows us to set `this`for it.
233
+
El segundo argumento opcional`mapFn`puede ser una función que se aplicará a cada elemento antes de agregarlo a la matriz, y`thisArg`permite establecer el `this`para ello.
233
234
234
-
For instance:
235
+
Por ejemplo:
235
236
236
237
```js
237
-
//assuming that range is taken from the example above
238
+
//suponiendo que range se toma del ejemplo anterior
238
239
239
-
//square each number
240
+
//el cuadrado de cada número
240
241
let arr =Array.from(range, num=> num * num);
241
242
242
243
alert(arr); // 1,4,9,16,25
243
244
```
244
245
245
-
Here we use `Array.from`to turn a string into an array of characters:
246
+
Aquí usamos `Array.from`para convertir una cadena en una matriz de caracteres:
246
247
247
248
```js run
248
249
let str ='𝒳😂';
@@ -255,24 +256,25 @@ alert(chars[1]); // 😂
255
256
alert(chars.length); // 2
256
257
```
257
258
258
-
Unlike `str.split`, it relies on the iterable nature of the string and so, just like `for..of`, correctly works with surrogate pairs.
259
-
260
-
Technically here it does the same as:
259
+
A diferencia de `str.split`, `Array.from` se basa en la naturaleza iterable de la cadena y, por lo tanto, al igual que `for..of`, funciona correctamente con pares sustitutos.
261
260
261
+
Técnicamente aquí hace lo mismo que:
262
+
262
263
```js run
263
264
let str ='𝒳😂';
264
265
265
-
let chars = []; // Array.from internally does the same loop
266
+
let chars = []; // Array.from internamente hace el mismo bucle
267
+
266
268
for (let char of str) {
267
269
chars.push(char);
268
270
}
269
271
270
272
alert(chars);
271
273
```
272
274
273
-
...But it is shorter.
275
+
... Pero es más corto.
274
276
275
-
We can even build surrogate-aware `slice`on it:
277
+
Incluso podemos construir un `segmento` o `slice`compatible con sustitutos en él:
276
278
277
279
```js run
278
280
functionslice(str, start, end) {
@@ -283,25 +285,26 @@ let str = '𝒳😂𩷶';
283
285
284
286
alert( slice(str, 1, 3) ); // 😂𩷶
285
287
286
-
//the native method does not support surrogate pairs
287
-
alert( str.slice(1, 3) ); // garbage (two pieces from different surrogate pairs)
288
+
//el método nativo no admite pares sustitutos
289
+
alert( str.slice(1, 3) ); // garbage (dos piezas de diferentes pares sustitutos)
288
290
```
289
291
290
292
291
-
## Summary
292
-
293
-
Objects that can be used in `for..of` are called *iterable*.
293
+
## Resumen
294
294
295
-
- 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.
298
-
- The `Symbol.iterator` method is called automatically by `for..of`, but we also can do it directly.
299
-
- Built-in iterables like strings or arrays, also implement `Symbol.iterator`.
300
-
- String iterator knows about surrogate pairs.
295
+
Los objetos que se pueden usar en `for..of` se denominan *iterables*.
301
296
297
+
- Técnicamente, los iterables deben implementar el método llamado `Symbol.iterator`.
298
+
- El resultado de `obj[Symbol.iterator]` se llama *iterador*. Maneja el proceso de iteración adicional.
299
+
- Un iterador debe tener el método llamado `next()` que devuelve un objeto `{done: Boolean, value: any}`, donde `done: true` denota el final de la iteración, de lo contrario, `value` es el siguiente valor.
300
+
- El método `Symbol.iterator` se llama automáticamente por `for..of`, pero también podemos hacerlo directamente.
301
+
- Los iterables integrados, como cadenas o matrices, también implementan `Symbol.iterator`.
302
+
- El iterador de cadena funciona con pares sustitutos.
303
+
302
304
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.
305
+
Los objetos que tienen propiedades indexadas y `longitud` o *length* se llaman *array-like*. Dichos objetos también pueden tener otras propiedades y métodos, pero carecen de los métodos integrados de las matrices.
304
306
305
-
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.
307
+
Si miramos dentro de la especificación, veremos que la mayoría de los métodos incorporados suponen que funcionan con iterables o array-likes en lugar de matrices "reales", porque eso es más abstracto.
306
308
307
-
`Array.from(obj[, mapFn, thisArg])` makes a real `Array` of an iterable or array-like `obj`, and we can then use array methods on it. The optional arguments `mapFn` and `thisArg` allow us to apply a function to each item.
309
+
`Array.from (obj[, mapFn, thisArg])` crea un verdadero `Array` de un `obj` iterable o array-like, y luego podemos usar métodos de matriz en él. Los argumentos opcionales `mapFn` y `thisArg` nos permiten aplicar una función a cada elemento.
0 commit comments