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/06-advanced-functions/09-call-apply-decorators/02-delay/solution.md
+3-3Lines changed: 3 additions & 3 deletions
Original file line number
Diff line number
Diff line change
@@ -14,11 +14,11 @@ let f1000 = delay(alert, 1000);
14
14
f1000("test"); // mostrar "test" después de 1000ms
15
15
```
16
16
17
-
Tenga en cuenta cómo se utiliza una función de flecha aquí. Como sabemos, las funciones de flecha no tienen contextos propios `this` ni `arguments`, por lo que `f.apply(this, arguments)` toma `this` y `arguments` del contenedor.
17
+
Tenga en cuenta cómo se utiliza una función de flecha aquí. Sabemos que las funciones de flecha no tienen contextos propios `this` ni `arguments`, por lo que `f.apply(this, arguments)` toma `this` y `arguments` del contenedor.
18
18
19
-
Si pasamos una función regular, `setTimeout`lo llamaría sin argumentos y`this = window` (suponiendo que estemos en el navegador).
19
+
Si pasamos una función regular, `setTimeout`la llamará sin argumentos y, suponiendo que estemos en el navegador, con `this = window`.
20
20
21
-
Todavía podemos pasar el `this` correcto usando una variable intermedia, pero eso es un poco más engorroso:
21
+
Todavía podemos pasar el `this` correcto usando una variable intermedia, pero eso es algo más engorroso:
Copy file name to clipboardExpand all lines: 1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/solution.md
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -9,4 +9,4 @@ function debounce(func, ms) {
9
9
10
10
```
11
11
12
-
Una llamada a `debounce` devuelve un contenedor wrapper. Cuando se le llama, planifica la llamada a la función original después de los `ms` dados y cancela el tiempo de espera anterior.
12
+
Una llamada a `debounce` devuelve un contenedor "wrapper". Cuando se lo llama, planifica la llamada a la función original después de los `ms` dados y cancela el tiempo de espera anterior.
Copy file name to clipboardExpand all lines: 1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md
+2-2Lines changed: 2 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -14,7 +14,7 @@ Entonces, si la función contenedora se llama a 0ms, 200ms y 500ms, y luego no h
14
14
15
15

16
16
17
-
... Y obtendrá los argumentos de la última llamada, y se ignorarán otras llamadas.
17
+
... Y obtendrá los argumentos de la última llamada, y se ignoran las otras llamadas.
18
18
19
19
Aquí está el código para ello (usa el decorador debounce del [Lodash library](https://lodash.com/docs/4.17.15#debounce):
20
20
@@ -40,7 +40,7 @@ En este ejemplo en vivo, el controlador coloca el resultado en un cuadro a conti
40
40
41
41
[iframe border=1 src="debounce" height=200]
42
42
43
-
¿Ve? La segunda entrada llama a la función debounce, por lo que su contenido se procesa después de 1000 ms desde la última entrada.
43
+
¿Lo ve? La segunda entrada llama a la función debounce, por lo que su contenido se procesa después de 1000 ms desde la última entrada.
44
44
```
45
45
46
46
Entonces, `debounce` es una excelente manera de procesar una secuencia de eventos: ya sea una secuencia de pulsaciones de teclas, movimientos del mouse u otra cosa.
Copy file name to clipboardExpand all lines: 1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/solution.md
+2-2Lines changed: 2 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -29,10 +29,10 @@ function throttle(func, ms) {
29
29
}
30
30
```
31
31
32
-
Una llamada a `throttle(func, ms)` devuelve un`wrapper`.
32
+
Una llamada a `throttle(func, ms)` devuelve el contenedor`wrapper`.
33
33
34
34
1. Durante la primera llamada, el `wrapper` solo ejecuta `func` y establece el estado de enfriamiento (`isThrottled = true`).
35
35
2. En este estado, todas las llamadas se memorizan en `savedArgs/savedThis`. Tenga en cuenta que tanto el contexto como los argumentos son igualmente importantes y deben memorizarse. Los necesitamos simultáneamente para reproducir la llamada.
36
-
3. Después de que pasan `ms` milisegundos, se activa `setTimeout`. El estado de enfriamiento se elimina (`isThrottled = false`) y, si ignoramos las llamadas,`wrapper` se ejecuta con los últimos argumentos y contexto memorizados.
36
+
3. Después de que pasan `ms` milisegundos, se activa `setTimeout`. El estado de enfriamiento se elimina (`isThrottled = false`) y, si ignoramos las llamadas,`wrapper` se ejecuta con los últimos argumentos y contexto memorizados.
37
37
38
38
El tercer paso no ejecuta `func`, sino `wrapper`, porque no solo necesitamos ejecutar `func`, sino que una vez más ingresamos al estado de enfriamiento y configuramos el tiempo de espera para restablecerlo.
Copy file name to clipboardExpand all lines: 1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md
+12-12Lines changed: 12 additions & 12 deletions
Original file line number
Diff line number
Diff line change
@@ -4,15 +4,15 @@ importance: 5
4
4
5
5
# Decorador throttle
6
6
7
-
Crea un decorador "throttling" `throttle(f, ms)` que devuelve un contenedor.
7
+
Crea un decorador "limitador" o "throttling" `throttle(f, ms)` que devuelve un contenedor.
8
8
9
9
Cuando se llama varias veces, pasa la llamada a `f` como máximo una vez por `ms` milisegundos.
10
10
11
-
La diferencia con *debounce* es que es un decorador completamente diferente:
12
-
-`debounce` ejecuta la función una vez después del período de `enfriamiento`. Es bueno para procesar el resultado final.
13
-
-`throttle`lo ejecuta no más de lo que se le da en el tiempo `ms`. Es bueno para actualizaciones regulares que no deberían ser muy frecuentes.
11
+
Comparado con el decorador *debounce*, el comportamiento es completamente diferente:
12
+
-`debounce` ejecuta la función una vez *después* del período de `enfriamiento`. Es bueno para procesar el resultado final.
13
+
-`throttle`la ejecuta una y no más veces por el tiempo de `ms` dado. Es bueno para actualizaciones regulares que no deberían ser muy frecuentes.
14
14
15
-
En otras palabras, "throttle" es como una secretaria que acepta llamadas telefónicas, pero molesta al jefe (llama a la "f" real) no más de una vez por milisegundos `ms`.
15
+
En otras palabras, "throttle" es como una secretaria que acepta llamadas telefónicas, pero molesta al jefe (llama a la "f" real) no más de una vez por `ms` milisegundos.
16
16
17
17
Revisemos una aplicación de la vida real para comprender mejor ese requisito y ver de dónde proviene.
18
18
@@ -21,16 +21,16 @@ Revisemos una aplicación de la vida real para comprender mejor ese requisito y
21
21
En un navegador, podemos configurar una función para que se ejecute en cada movimiento del mouse y obtener la ubicación del puntero a medida que se mueve. Durante un uso activo del mouse, esta función generalmente se ejecuta con mucha frecuencia, puede ser algo así como 100 veces por segundo (cada 10 ms).
22
22
**Nos gustaría actualizar cierta información en la página web cuando se mueve el puntero.**
23
23
24
-
...Pero la función de actualización `update()` es demasiado pesada para hacerlo en cada micro-movimiento. Tampoco tiene sentido actualizar más de una vez cada 100 ms.
24
+
...Pero la función de actualización `update()` es demasiado pesada para hacerlo en cada micro-movimiento. Tampoco tiene sentido actualizar más de una vez cada 100 ms.
25
25
26
-
Entonces lo envolveremos en el decorador: para ejecutar en cada movimiento del mouse, usamos `throttle(update, 100)` en lugar del `update()` original. Se llamará al decorador con frecuencia, pero reenviará la llamada a `update()` como máximo una vez cada 100 ms.
26
+
Entonces lo envolveremos en el decorador: para ejecutar en cada movimiento del mouse, usamos `throttle(update, 100)` en lugar del `update()` original. Se llamará al decorador con frecuencia, pero este reenviará la llamada a `update()` como máximo una vez cada 100 ms.
27
27
28
28
Visualmente, se verá así:
29
29
30
-
1. Para el primer movimiento del mouse, el variante decorador pasa inmediatamente la llamada a `update`. Eso es importante, el usuario ve nuestra reacción a su movimiento de inmediato
31
-
2. Luego, a medida que el mouse avanza, hasta `100ms` no sucede nada. La variante decorador ignora las llamadas.
32
-
3. Al final de`100ms` -- ocurre un `update` más con las últimas coordenadas.
33
-
4. Entonces, finalmente, el mouse se detiene en alguna parte. La variante decorador espera hasta que expire`100ms` y luego ejecuta `update` con las últimas coordenadas. Entonces, y esto es bastante importante, se procesan las coordenadas finales del mouse.
30
+
1. Para el primer movimiento del mouse, la variante decorada pasa inmediatamente la llamada a `update`. Esto es importante, el usuario ve nuestra reacción a su movimiento de inmediato.
31
+
2. Luego, a medida que el mouse avanza, hasta `100ms` no sucede nada. La variante decorada ignora las llamadas.
32
+
3. Al final de`100ms` -- ocurre un `update` más con las últimas coordenadas.
33
+
4. Entonces, finalmente, el mouse se detiene en alguna parte. La variante decorada espera hasta que expiren`100ms` y luego ejecuta `update` con las últimas coordenadas. Entonces, y esto es muy importante, se procesan las coordenadas finales del mouse.
Copy file name to clipboardExpand all lines: 1-js/06-advanced-functions/09-call-apply-decorators/article.md
+20-20Lines changed: 20 additions & 20 deletions
Original file line number
Diff line number
Diff line change
@@ -1,16 +1,16 @@
1
1
# Decoradores y redirecciones, call/apply
2
2
3
-
JavaScript ofrece una flexibilidad excepcional cuando se trata de funciones. Se pueden pasar, usar como objetos, y ahora veremos cómo *redirigir* las llamadas entre ellos y *decorarlos*.
3
+
JavaScript ofrece una flexibilidad excepcional cuando se trata de funciones. Se pueden pasar, usar como objetos, y ahora veremos cómo *redirigir* las llamadas entre ellas y *decorarlas*.
4
4
5
5
## Caché transparente
6
6
7
-
Digamos que tenemos una función `slow(x)` que es pesada para la CPU, pero sus resultados son estables. En otras palabras, la misma `x` siempre devuelve el mismo resultado.
7
+
Digamos que tenemos una función `slow(x)`, que es pesada para la CPU pero cuyos resultados son "estables": es decir que con la misma `x` siempre devuelve el mismo resultado.
8
8
9
-
Si la función se llama con frecuencia, es posible que queramos almacenar en caché (recordar) los resultados para evitar perder tiempo extra en nuevos cálculos.
9
+
Si la función se llama con frecuencia, es posible que queramos almacenar en caché (recordar) los resultados obtenidos para evitar perder tiempo en calcularlos de nuevo.
10
10
11
-
Pero en lugar de agregar esa funcionalidad en `slow()` crearemos una función de contenedor, que agrega almacenamiento en caché. Como veremos, hacer esto trae beneficios.
11
+
Pero en lugar de agregar esta funcionalidad en `slow()`, crearemos una función contenedora (en inglés "wrapper", envoltorio) que agregue almacenamiento en caché. Como veremos, hacer esto tiene sus beneficios.
12
12
13
-
Aquí está el código, y siguiendo las explicaciones:
13
+
Aquí está el código, seguido por su explicación:
14
14
15
15
```js run
16
16
functionslow(x) {
@@ -29,7 +29,7 @@ function cachingDecorator(func) {
29
29
30
30
let result =func(x); // de lo contrario llame a func
31
31
32
-
cache.set(x, result); // y cacheamos (recordamos) el resultado
32
+
cache.set(x, result); // y almacenamos en caché (recordamos) el resultado
33
33
return result;
34
34
};
35
35
}
@@ -236,9 +236,9 @@ Hay muchas posibles soluciones:
236
236
237
237
Para muchas aplicaciones prácticas, la tercera variante es lo suficientemente buena, por lo que nos mantendremos en esa opción.
238
238
239
-
También necesitamos pasar no solo `x`, sino todos los argumentos en `func.call`. Recordemos que en una `función()`podemos obtener un pseudo-array (*array-like*) de sus argumentos como `arguments`, por lo que `func.call(this, x)` debería reemplazarse por `func.call(this, ...arguments)`.
239
+
También necesitamos pasar no solo `x` sino todos los argumentos en `func.call`. Recordemos que en una `función()`, con el uso de `arguments`podemos obtener un pseudo-array de sus argumentos, así que `func.call(this, x)` debería reemplazarse por `func.call(this, ...arguments)`.
240
240
241
-
Aquí un mejorado y poderosísimo`cachingDecorator`:
241
+
Aquí un mejorado y más potente`cachingDecorator`:
242
242
243
243
```js run
244
244
let worker = {
@@ -286,7 +286,7 @@ Hay dos cambios:
286
286
287
287
## func.apply
288
288
289
-
En vez de `func.call(this, ...arguments)` nosotros podríamos usar `func.apply(this, arguments)`.
289
+
En vez de `func.call(this, ...arguments)`, podríamos usar `func.apply(this, arguments)`.
290
290
291
291
La sintaxis del método incorporado [func.apply](https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/Function/apply) es:
292
292
@@ -309,10 +309,10 @@ Estas hacen la misma llamada de `func` con el contexto y argumento dados.
309
309
310
310
Solo hay una sutil diferencia con respect○ a `args`:
311
311
312
-
- La sintaxis extendida `...`permite pasar un *iterable*`args` como una lista para `call`.
313
-
- La opción `apply` acepta solo`args`como *array-like*.
312
+
- La sintaxis con el operador "spread" `...`-- en `call` permite pasar una lista *iterable*`args`.
313
+
- La opción `apply`-- acepta solamente`args`que sean *símil-array*.
314
314
315
-
Y para los objetos que son iterables y array-like, como un array real, podemos usar cualquiera de ellos, pero `apply` probablemente será más rápido, porque la mayoría de los motores de JavaScript lo optimizan mejor internamente.
315
+
Para los objetos que son iterables y símil-array, como un array real, podemos usar cualquiera de ellos, pero `apply` probablemente será más rápido porque la mayoría de los motores de JavaScript lo optimizan mejor internamente.
316
316
317
317
Pasar todos los argumentos junto con el contexto a otra función se llama *redirección de llamadas*.
318
318
@@ -324,7 +324,7 @@ let wrapper = function() {
324
324
};
325
325
```
326
326
327
-
Cuando un código externo llama a tal `wrapper`, no se puede distinguir de la llamada de la función original `func` .
327
+
Cuando un código externo llama a tal contenedor `wrapper`, no se puede distinguir de la llamada de la función original `func` .
328
328
329
329
## Préstamo de método [#method-borrowing]
330
330
@@ -346,7 +346,7 @@ function hash(args) {
346
346
}
347
347
```
348
348
349
-
... Desafortunadamente, eso no funcionará. Debido a que estamos llamando a `hash (arguments)`, y el objeto `arguments` es iterable y *array-like* (similar a un array, pero no es un array real).
349
+
... desafortunadamente, eso no funcionará. Esto es debido a que estamos llamando a `hash (arguments)`, y el objeto `arguments` es iterable y *símil-array* (no es un array real).
350
350
351
351
Por lo tanto, llamar a `join` en él fallará, como podemos ver a continuación:
352
352
@@ -390,28 +390,28 @@ Tomado de la especificación casi "tal cual":
390
390
6. ...hacerlo hasta que la cantidad `this.length` de elementos estén adheridos.
391
391
7. Devolver `result`.
392
392
393
-
Entonces, técnicamente `this` une `this[0]`, `this[1]`...etc. Está escrito intencionalmente de una manera que permite cualquier tipo de array `this` (no es una coincidencia, muchos métodos siguen esta práctica). Es por eso que también funciona con `this = arguments`
393
+
Entonces, técnicamente toma a `this`y le une `this[0]`, `this[1]`...etc. Está escrito intencionalmente de una manera que permite cualquier tipo de array `this` (no es una coincidencia, muchos métodos siguen esta práctica). Es por eso que también funciona con `this = arguments`
394
394
395
395
## Decoradores y propiedades de funciones
396
396
397
397
Por lo general, es seguro reemplazar una función o un método con un decorador, excepto por una pequeña cosa. Si la función original tenía propiedades (como `func.calledCount` o cualquier otra) entonces la función decoradora no las proporcionará. Porque es una envoltura. Por lo tanto, se debe tener cuidado al usarlo.
398
398
399
399
En el ejemplo anterior, si la función `slow` tuviera propiedades, `cachingDecorator(slow)` sería un contenedor sin dichas propiedades.
400
400
401
-
Algunos decoradores pueden proporcionar sus propias propiedades. P.ej. un decorador puede contar cuántas veces se invocó una función y cuánto tiempo tardó, y exponer esta información a través de propiedades de envoltura.
401
+
Algunos decoradores pueden proporcionar sus propias propiedades. P.ej. un decorador puede contar cuántas veces se invocó una función y cuánto tiempo tardó, y exponer esta información por medio de propiedades del contenedor.
402
402
403
403
Existe una forma de crear decoradores que mantienen el acceso a las propiedades de la función, pero esto requiere el uso de un objeto especial `Proxy` para ajustar una función. Lo discutiremos más adelante en el artículo <info:proxy#proxy-apply>.
404
404
405
405
## Resumen
406
406
407
-
*Decorator* o decorador es un contenedor alrededor de una función que altera su comportamiento. El trabajo principal todavía lo realiza la función.
407
+
El *decorador* es un contenedor alrededor de una función que altera su comportamiento. El trabajo principal todavía lo realiza la función.
408
408
409
409
Los decoradores se pueden ver como "características" o "aspectos" que se pueden agregar a una función. Podemos agregar uno o agregar muchos. ¡Y todo esto sin cambiar su código!
410
410
411
-
Para implementar `cachingDecorator`, estudiamos los siguientes métodos:
411
+
Para implementar `cachingDecorator`, hemos estudiado los siguientes métodos:
412
412
413
413
-[func.call(context, arg1, arg2...)](https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/Function/call) -- llama a `func` con el contexto y argumentos dados.
414
-
-[func.apply(context, args)](https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/Function/apply) -- llama a `func` pasando `context` como `this` y array-like`args`en una lista de argumentos.
414
+
-[func.apply(context, args)](https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/Function/apply) -- llama a `func`, pasando `context` como `this`, y un símil-array`args`como lista de argumentos.
415
415
416
416
La *redirección de llamadas* genérica generalmente se realiza con `apply`:
417
417
@@ -421,6 +421,6 @@ let wrapper = function() {
421
421
};
422
422
```
423
423
424
-
También vimos un ejemplo de *préstamo de método* cuando tomamos un método de un objeto y lo `llamamos` en el contexto de otro objeto. Es bastante común tomar métodos de array y aplicarlos al símil-array `arguments`. La alternativa es utilizar el objeto de parámetros rest que es un array real.
424
+
También vimos un ejemplo de *préstamo de método* cuando tomamos un método de un objeto y lo "llamamos" (`call`) en el contexto de otro objeto. Es bastante común tomar métodos de array y aplicarlos al símil-array `arguments`. La alternativa es utilizar el objeto de parámetros rest, que es un array real.
425
425
426
426
Hay muchos decoradores a tu alrededor. Verifica qué tan bien los entendiste resolviendo las tareas de este capítulo.
0 commit comments