diff --git a/1-js/06-advanced-functions/10-bind/2-write-to-object-after-bind/solution.md b/1-js/06-advanced-functions/10-bind/2-write-to-object-after-bind/solution.md index 737a14481..7b786e286 100644 --- a/1-js/06-advanced-functions/10-bind/2-write-to-object-after-bind/solution.md +++ b/1-js/06-advanced-functions/10-bind/2-write-to-object-after-bind/solution.md @@ -1,4 +1,4 @@ -The answer: `null`. +Respuesta: `null`. ```js run @@ -13,6 +13,6 @@ let user = { user.g(); ``` -The context of a bound function is hard-fixed. There's just no way to further change it. +El contexto de una función enlazada es fijo. Simplemente no hay forma de cambiarlo más. -So even while we run `user.g()`, the original function is called with `this=null`. +Entonces, incluso mientras ejecutamos `user.g()`, la función original se llama con `this = null`. diff --git a/1-js/06-advanced-functions/10-bind/2-write-to-object-after-bind/task.md b/1-js/06-advanced-functions/10-bind/2-write-to-object-after-bind/task.md index 6d7e1fb24..c9bb09d58 100644 --- a/1-js/06-advanced-functions/10-bind/2-write-to-object-after-bind/task.md +++ b/1-js/06-advanced-functions/10-bind/2-write-to-object-after-bind/task.md @@ -2,9 +2,9 @@ importance: 5 --- -# Bound function as a method +# Función enlazada como método -What will be the output? +¿Cuál será el resultado? ```js function f() { diff --git a/1-js/06-advanced-functions/10-bind/3-second-bind/solution.md b/1-js/06-advanced-functions/10-bind/3-second-bind/solution.md index 97e1c2809..aa3d2f20b 100644 --- a/1-js/06-advanced-functions/10-bind/3-second-bind/solution.md +++ b/1-js/06-advanced-functions/10-bind/3-second-bind/solution.md @@ -1,4 +1,4 @@ -The answer: **John**. +Respuesta: **John**. ```js run no-beautify function f() { @@ -10,6 +10,6 @@ f = f.bind( {name: "John"} ).bind( {name: "Pete"} ); f(); // John ``` -The exotic [bound function](https://tc39.github.io/ecma262/#sec-bound-function-exotic-objects) object returned by `f.bind(...)` remembers the context (and arguments if provided) only at creation time. +El objeto exótico [bound function](https://tc39.github.io/ecma262/#sec-bound-function-exotic-objects) devuelto por `f.bind(...)` recuerda el contexto (y los argumentos si se proporcionan) solo en el momento de la creación. -A function cannot be re-bound. +Una función no se puede volver a vincular. diff --git a/1-js/06-advanced-functions/10-bind/3-second-bind/task.md b/1-js/06-advanced-functions/10-bind/3-second-bind/task.md index 5daf053c6..dd6821223 100644 --- a/1-js/06-advanced-functions/10-bind/3-second-bind/task.md +++ b/1-js/06-advanced-functions/10-bind/3-second-bind/task.md @@ -2,11 +2,11 @@ importance: 5 --- -# Second bind +# Segundo enlace -Can we change `this` by additional binding? +¿Podemos cambiar `this` por un enlace adicional? -What will be the output? +¿Cuál será el resultado? ```js no-beautify function f() { diff --git a/1-js/06-advanced-functions/10-bind/4-function-property-after-bind/solution.md b/1-js/06-advanced-functions/10-bind/4-function-property-after-bind/solution.md index 181555d95..b5cfc3c6f 100644 --- a/1-js/06-advanced-functions/10-bind/4-function-property-after-bind/solution.md +++ b/1-js/06-advanced-functions/10-bind/4-function-property-after-bind/solution.md @@ -1,4 +1,4 @@ -The answer: `undefined`. +Respuesta: `undefined`. -The result of `bind` is another object. It does not have the `test` property. +El resultado de `bind` es otro objeto. No tiene la propiedad `test`. diff --git a/1-js/06-advanced-functions/10-bind/4-function-property-after-bind/task.md b/1-js/06-advanced-functions/10-bind/4-function-property-after-bind/task.md index d6cfb44bf..c82938452 100644 --- a/1-js/06-advanced-functions/10-bind/4-function-property-after-bind/task.md +++ b/1-js/06-advanced-functions/10-bind/4-function-property-after-bind/task.md @@ -2,9 +2,10 @@ importance: 5 --- -# Function property after bind +# Propiedad de función después del enlace -There's a value in the property of a function. Will it change after `bind`? Why, or why not? + +Hay un valor en la propiedad de una función. ¿Cambiará después de `bind`? ¿Por qué sí o por qué no? ```js run function sayHi() { @@ -17,7 +18,7 @@ let bound = sayHi.bind({ name: "John" }); -alert( bound.test ); // what will be the output? why? +alert( bound.test ); // ¿Cuál será la salida? ¿por qué? */!* ``` diff --git a/1-js/06-advanced-functions/10-bind/5-question-use-bind/solution.md b/1-js/06-advanced-functions/10-bind/5-question-use-bind/solution.md index 403107ca6..bf079db40 100644 --- a/1-js/06-advanced-functions/10-bind/5-question-use-bind/solution.md +++ b/1-js/06-advanced-functions/10-bind/5-question-use-bind/solution.md @@ -1,9 +1,9 @@ -The error occurs because `ask` gets functions `loginOk/loginFail` without the object. +El error se produce porque `ask` obtiene las funciones `loginOk/loginFail` sin el objeto. -When it calls them, they naturally assume `this=undefined`. +Cuando los llama, asumen naturalmente `this = undefined`. -Let's `bind` the context: +Vamos a usar `bind` para enlazar el contexto: ```js run function askPassword(ok, fail) { @@ -30,14 +30,18 @@ askPassword(user.loginOk.bind(user), user.loginFail.bind(user)); */!* ``` -Now it works. +Ahora funciona. -An alternative solution could be: +Una solución alternativa podría ser: ```js //... askPassword(() => user.loginOk(), () => user.loginFail()); ``` -Usually that also works and looks good. + +Por lo general, eso también funciona y se ve bien. + +Aunque es un poco menos confiable en situaciones más complejas donde la variable `user` podría cambiar *después* de que se llama a `askPassword`, *antes* de que el visitante responde y llame a `() => user.loginOk ()`. + It's a bit less reliable though in more complex situations where `user` variable might change *after* `askPassword` is called, but *before* the visitor answers and calls `() => user.loginOk()`. diff --git a/1-js/06-advanced-functions/10-bind/5-question-use-bind/task.md b/1-js/06-advanced-functions/10-bind/5-question-use-bind/task.md index fe6a9b4eb..e641341b4 100644 --- a/1-js/06-advanced-functions/10-bind/5-question-use-bind/task.md +++ b/1-js/06-advanced-functions/10-bind/5-question-use-bind/task.md @@ -2,13 +2,14 @@ importance: 5 --- -# Fix a function that loses "this" -The call to `askPassword()` in the code below should check the password and then call `user.loginOk/loginFail` depending on the answer. +# Arreglar una función que perdió "this" -But it leads to an error. Why? +La llamada a `askPassword()` en el código a continuación debe verificar la contraseña y luego llamar a `user.loginOk/loginFail` dependiendo de la respuesta. -Fix the highlighted line for everything to start working right (other lines are not to be changed). +Pero lleva a un error. ¿Por qué? + +Arregle la línea resaltada para que todo comience a funcionar correctamente (no se deben cambiar otras líneas). ```js run function askPassword(ok, fail) { diff --git a/1-js/06-advanced-functions/10-bind/6-ask-partial/solution.md b/1-js/06-advanced-functions/10-bind/6-ask-partial/solution.md index 3284c943b..b6f4f60dd 100644 --- a/1-js/06-advanced-functions/10-bind/6-ask-partial/solution.md +++ b/1-js/06-advanced-functions/10-bind/6-ask-partial/solution.md @@ -1,14 +1,17 @@ -1. Either use a wrapper function, an arrow to be concise: + +1. Utilice una función wrapper (envoltura), de tipo arrow (flecha) para ser conciso: ```js askPassword(() => user.login(true), () => user.login(false)); ``` - Now it gets `user` from outer variables and runs it the normal way. -2. Or create a partial function from `user.login` that uses `user` as the context and has the correct first argument: + Ahora obtiene `user` de variables externas y lo ejecuta de la manera normal. + +2. O cree una función parcial desde `user.login` que use `user` como contexto y tenga el primer argumento correcto: + ```js diff --git a/1-js/06-advanced-functions/10-bind/6-ask-partial/task.md b/1-js/06-advanced-functions/10-bind/6-ask-partial/task.md index c90851c2b..48a949b8c 100644 --- a/1-js/06-advanced-functions/10-bind/6-ask-partial/task.md +++ b/1-js/06-advanced-functions/10-bind/6-ask-partial/task.md @@ -2,13 +2,15 @@ importance: 5 --- -# Partial application for login -The task is a little more complex variant of . +# Aplicación parcial para inicio de sesión -The `user` object was modified. Now instead of two functions `loginOk/loginFail`, it has a single function `user.login(true/false)`. +La tarea es una variante un poco más compleja de . + +El objeto `user` fue modificado. Ahora, en lugar de dos funciones `loginOk/loginFail`, tiene una sola función `user.login(true/false) `. + +¿Qué deberíamos pasar a `askPassword` en el código a continuación, para que llame a `user.login(true)` como `ok` y `user.login(false)` como `fail`? -What should we pass `askPassword` in the code below, so that it calls `user.login(true)` as `ok` and `user.login(false)` as `fail`? ```js function askPassword(ok, fail) { @@ -30,5 +32,7 @@ askPassword(?, ?); // ? */!* ``` -Your changes should only modify the highlighted fragment. + +Sus cambios solo deberían modificar el fragmento resaltado. + diff --git a/1-js/06-advanced-functions/10-bind/article.md b/1-js/06-advanced-functions/10-bind/article.md index 787c7d68e..6df39ce9f 100644 --- a/1-js/06-advanced-functions/10-bind/article.md +++ b/1-js/06-advanced-functions/10-bind/article.md @@ -3,17 +3,21 @@ libs: --- -# Function binding +# Función binding (vinculadora) -When passing object methods as callbacks, for instance to `setTimeout`, there's a known problem: "losing `this`". -In this chapter we'll see the ways to fix it. +Al pasar métodos de objeto como devoluciones de llamada, por ejemplo a `setTimeout`, se genera un problema conocido: "pérdida de `this`". -## Losing "this" +En este capítulo veremos las formas de solucionarlo. -We've already seen examples of losing `this`. Once a method is passed somewhere separately from the object -- `this` is lost. -Here's how it may happen with `setTimeout`: +## Pérdida de "this" + + +Ya hemos visto ejemplos de pérdida de `this`. Una vez que se pasa un método en algún lugar separado del objeto -- `this` se pierde. + + +Así es como puede suceder con `setTimeout`: ```js run let user = { @@ -28,22 +32,24 @@ setTimeout(user.sayHi, 1000); // Hello, undefined! */!* ``` -As we can see, the output shows not "John" as `this.firstName`, but `undefined`! +Como podemos ver, el resultado no muestra "John" como `this.firstName`, ¡sino como `undefined`! -That's because `setTimeout` got the function `user.sayHi`, separately from the object. The last line can be rewritten as: +Esto se debe a que `setTimeout` tiene la función `user.sayHi`, separada del objeto. La última línea se puede reescribir como: ```js let f = user.sayHi; -setTimeout(f, 1000); // lost user context +setTimeout(f, 1000); // user pierde el contexto ``` -The method `setTimeout` in-browser is a little special: it sets `this=window` for the function call (for Node.js, `this` becomes the timer object, but doesn't really matter here). So for `this.firstName` it tries to get `window.firstName`, which does not exist. In other similar cases, usually `this` just becomes `undefined`. -The task is quite typical -- we want to pass an object method somewhere else (here -- to the scheduler) where it will be called. How to make sure that it will be called in the right context? +El método `setTimeout` en el navegador es un poco especial: establece `this = window` para la llamada a la función (para Node.js, `this` se convierte en el objeto temporizador (timer), pero realmente no importa aquí). Entonces, en `this.firstName` intenta obtener `window.firstName`, que no existe. En otros casos similares, `this` simplemente se vuelve `undefined`. -## Solution 1: a wrapper -The simplest solution is to use a wrapping function: +La tarea es bastante típica --queremos pasar un método de objeto a otro lugar (aquí --al planificador) donde se llamará. ¿Cómo asegurarse de que se llamará en el contexto correcto? + +## Solución 1: un wrapper (envoltura) + +La solución más simple es usar una función wrapper (envoltura): ```js run let user = { @@ -60,17 +66,17 @@ setTimeout(function() { */!* ``` -Now it works, because it receives `user` from the outer lexical environment, and then calls the method normally. +Ahora funciona, porque recibe a `user` del entorno léxico externo, y luego llama al método normalmente. -The same, but shorter: +Aquí hacemos lo mismo, pero de otra manera: ```js setTimeout(() => user.sayHi(), 1000); // Hello, John! ``` -Looks fine, but a slight vulnerability appears in our code structure. +Se ve bien, pero aparece una ligera vulnerabilidad en nuestra estructura de código.. -What if before `setTimeout` triggers (there's one second delay!) `user` changes value? Then, suddenly, it will call the wrong object! +¿Qué pasa si antes de que `setTimeout` se active (¡hay un segundo retraso!) `user` cambia el valor? Entonces, de repente, ¡llamará al objeto equivocado! ```js run @@ -83,32 +89,38 @@ let user = { setTimeout(() => user.sayHi(), 1000); -// ...the value of user changes within 1 second + +// ...el valor de user cambia en 1 segundo + user = { sayHi() { alert("Another user in setTimeout!"); } }; -// Another user in setTimeout! + +// Otro user en setTimeout! + ``` -The next solution guarantees that such thing won't happen. +La siguiente solución garantiza que tal cosa no sucederá. -## Solution 2: bind +## Solución 2: bind -Functions provide a built-in method [bind](mdn:js/Function/bind) that allows to fix `this`. +Las funciones proporcionan un método incorporado [bind](mdn:js/Function/bind) que permite encontrar a `this`. -The basic syntax is: +La sintaxis básica es: ```js -// more complex syntax will come a little later + +// la sintaxis más compleja vendrá un poco más tarde + let boundFunc = func.bind(context); ``` -The result of `func.bind(context)` is a special function-like "exotic object", that is callable as function and transparently passes the call to `func` setting `this=context`. +El resultado de `func.bind(context)` es un "objeto exótico", una función similar a una función regular, que se puede llamar como función y pasa la llamada de forma transparente a `func` estableciendo `this = context`. -In other words, calling `boundFunc` is like `func` with fixed `this`. +En otras palabras, llamar a `boundFunc` es como `func` con un `this` fijo. -For instance, here `funcUser` passes a call to `func` with `this=user`: +Por ejemplo, aquí `funcUser` pasa una llamada a `func` con `this = user`: ```js run let user = { @@ -125,9 +137,9 @@ funcUser(); // John */!* ``` -Here `func.bind(user)` as a "bound variant" of `func`, with fixed `this=user`. +Aquí `func.bind(user)` es como una "variante ligada" de `func`, con `this = user` fijo en ella. -All arguments are passed to the original `func` "as is", for instance: +Todos los argumentos se pasan al `func` original "tal cual", por ejemplo: ```js run let user = { @@ -138,15 +150,15 @@ function func(phrase) { alert(phrase + ', ' + this.firstName); } -// bind this to user +// vincula this a user let funcUser = func.bind(user); *!* -funcUser("Hello"); // Hello, John (argument "Hello" is passed, and this=user) +funcUser("Hello"); // Hello, John (argumento "Hello" se pasa, y this=user) */!* ``` -Now let's try with an object method: +Ahora intentemos con un método de objeto: ```js run @@ -161,21 +173,23 @@ let user = { let sayHi = user.sayHi.bind(user); // (*) */!* -// can run it without an object +// puede ejecutarlo sin un objeto + sayHi(); // Hello, John! setTimeout(sayHi, 1000); // Hello, John! -// even if the value of user changes within 1 second -// sayHi uses the pre-bound value +// incluso si el valor del usuario cambia en 1 segundo +// sayHi usa el valor pre-enlazado + user = { sayHi() { alert("Another user in setTimeout!"); } }; ``` -In the line `(*)` we take the method `user.sayHi` and bind it to `user`. The `sayHi` is a "bound" function, that can be called alone or passed to `setTimeout` -- doesn't matter, the context will be right. +En la línea `(*)` tomamos el método `user.sayHi` y lo vinculamos a `user`. `sayHi` es una función "bound" (enlazada). Si se llama sola o se pasa en `setTimeout` no importa, el contexto será el correcto. -Here we can see that arguments are passed "as is", only `this` is fixed by `bind`: +Aquí podemos ver que los argumentos se pasan "tal cual", solo que `this` se fija mediante` bind`: ```js run let user = { @@ -187,12 +201,12 @@ let user = { let say = user.say.bind(user); -say("Hello"); // Hello, John ("Hello" argument is passed to say) +say("Hello"); // Hello, John ("Hello" se pasa a say) say("Bye"); // Bye, John ("Bye" is passed to say) ``` -````smart header="Convenience method: `bindAll`" -If an object has many methods and we plan to actively pass it around, then we could bind them all in a loop: +````smart header="Convenience method:bindAll" +Si un objeto tiene muchos métodos y planeamos pasarlo activamente, podríamos vincularlos a todos en un bucle: ```js for (let key in user) { @@ -202,24 +216,27 @@ for (let key in user) { } ``` -JavaScript libraries also provide functions for convenient mass binding , e.g. [_.bindAll(obj)](http://lodash.com/docs#bindAll) in lodash. +Las bibliotecas de JavaScript también proporcionan funciones para un enlace masivo, e.j. [_.bindAll(obj)](http://lodash.com/docs#bindAll) en lodash. ```` -## Partial functions +## Funciones parciales -Until now we have only been talking about binding `this`. Let's take it a step further. +Hasta ahora solo hemos estado hablando de vincular `this`. Vamos un paso más allá. -We can bind not only `this`, but also arguments. That's rarely done, but sometimes can be handy. +Podemos vincular no solo `this`, sino también argumentos. Es algo que no suele hacerse, pero a veces puede ser útil. + +Sintáxis completa de `bind`: -The full syntax of `bind`: ```js let bound = func.bind(context, [arg1], [arg2], ...); ``` -It allows to bind context as `this` and starting arguments of the function. -For instance, we have a multiplication function `mul(a, b)`: +Permite vincular el contexto como `this` y los argumentos iniciales de la función. + +Por ejemplo, tenemos una función de multiplicación `mul(a, b)`: + ```js function mul(a, b) { @@ -227,7 +244,9 @@ function mul(a, b) { } ``` -Let's use `bind` to create a function `double` on its base: + +Usemos `bind` para crear una función` double` en su base: + ```js run function mul(a, b) { @@ -243,13 +262,15 @@ alert( double(4) ); // = mul(2, 4) = 8 alert( double(5) ); // = mul(2, 5) = 10 ``` -The call to `mul.bind(null, 2)` creates a new function `double` that passes calls to `mul`, fixing `null` as the context and `2` as the first argument. Further arguments are passed "as is". -That's called [partial function application](https://en.wikipedia.org/wiki/Partial_application) -- we create a new function by fixing some parameters of the existing one. +La llamada a `mul.bind(null, 2)` crea una nueva función `double` que pasa las llamadas a `mul`, fijando `null` como contexto y `2` como primer argumento. Otros argumentos se pasan "tal cual". + +Eso se llama [aplicación parcial de una función](https://en.wikipedia.org/wiki/Partial_application) -- creamos una nueva función arreglando algunos parámetros de la existente. + +Tenga en cuenta que aquí en realidad no usamos `this`. Pero `bind` lo requiere, por lo que debemos poner algo como `null`. -Please note that here we actually don't use `this` here. But `bind` requires it, so we must put in something like `null`. +La función `triple` en el siguiente código triplica el valor: -The function `triple` in the code below triples the value: ```js run function mul(a, b) { @@ -265,23 +286,23 @@ alert( triple(4) ); // = mul(3, 4) = 12 alert( triple(5) ); // = mul(3, 5) = 15 ``` -Why do we usually make a partial function? +¿Por qué solemos hacer una función parcial? -The benefit is that we can create an independent function with a readable name (`double`, `triple`). We can use it and not provide the first argument every time as it's fixed with `bind`. +El beneficio es que podemos crear una función independiente con un nombre legible (`double`,`triple`). Podemos usarlo y no proporcionar el primer argumento cada vez, ya que se fija con `bind`. -In other cases, partial application is useful when we have a very generic function and want a less universal variant of it for convenience. +En otros casos, la aplicación parcial es útil cuando tenemos una función muy genérica y queremos una variante menos universal para mayor comodidad. -For instance, we have a function `send(from, to, text)`. Then, inside a `user` object we may want to use a partial variant of it: `sendTo(to, text)` that sends from the current user. +Por ejemplo, tenemos una función `send(from, to, text)`. Luego, dentro de un objeto `user` podemos querer usar una variante parcial del mismo: `sendTo(to, text)` que envía desde el usuario actual. -## Going partial without context +## Parcial sin contexto -What if we'd like to fix some arguments, but not the context `this`? For example, for an object method. +¿Qué pasa si nos gustaría fijar algunos argumentos, pero no el contexto `this`? Por ejemplo, para un método de objeto. -The native `bind` does not allow that. We can't just omit the context and jump to arguments. +El método `bind` nativo no permite eso. No podemos simplemente omitir el contexto y saltar a los argumentos. -Fortunately, a function `partial` for binding only arguments can be easily implemented. +Afortunadamente, se puede implementar fácilmente una función `parcial` para vincular solo argumentos. -Like this: +Como esto: ```js run *!* @@ -292,7 +313,9 @@ function partial(func, ...argsBound) { } */!* -// Usage: + +// Uso: + let user = { firstName: "John", say(time, phrase) { @@ -300,29 +323,33 @@ let user = { } }; -// add a partial method with fixed time + +// agregar un método parcial con tiempo fijo user.sayNow = partial(user.say, new Date().getHours() + ':' + new Date().getMinutes()); user.sayNow("Hello"); -// Something like: +// Algo como: // [10:00] John: Hello! ``` -The result of `partial(func[, arg1, arg2...])` call is a wrapper `(*)` that calls `func` with: -- Same `this` as it gets (for `user.sayNow` call it's `user`) -- Then gives it `...argsBound` -- arguments from the `partial` call (`"10:00"`) -- Then gives it `...args` -- arguments given to the wrapper (`"Hello"`) +El resultado de la llamada `parcial(func [, arg1, arg2 ...])` es un contenedor `(*)` que llama a `func` con: +- El mismo `this` (para la llamada a `user.sayNow` es `user`) +- Luego le da `...argsBound` -- argumentos desde la llamada a `partial` (`"10:00"`) +- Luego le da `...args` -- argumentos dados desde la envoltura (`"Hello"`) + +Muy fácil de hacer con la sintaxis de propagación, ¿verdad? + +También hay una implementación preparada [_.partial](https://lodash.com/docs#partial) desde la librería lodash. + +## Resumen -So easy to do it with the spread syntax, right? +El método `func.bind(context, ... args)` devuelve una "variante ligada" de la función `func` que fija el contexto `this` y los primeros argumentos si se dan. -Also there's a ready [_.partial](https://lodash.com/docs#partial) implementation from lodash library. +Por lo general, aplicamos `bind` para fijar `this` a un método de objeto, de modo que podamos pasarlo en otro lugar. Por ejemplo, en `setTimeout`. -## Summary -Method `func.bind(context, ...args)` returns a "bound variant" of function `func` that fixes the context `this` and first arguments if given. +Cuando fijamos algunos argumentos de una función existente, la función resultante (menos universal) se llama *aplicación parcial* o *parcial*. -Usually we apply `bind` to fix `this` for an object method, so that we can pass it somewhere. For example, to `setTimeout`. -When we fix some arguments of an existing function, the resulting (less universal) function is called *partially applied* or *partial*. +Los parciales son convenientes cuando no queremos repetir el mismo argumento una y otra vez. Al igual que si tenemos una función `send(from, to)`, y `from` siempre debe ser igual para nuestra tarea, entonces, podemos obtener un parcial y continuar la tarea con él. -Partials are convenient when we don't want to repeat the same argument over and over again. Like if we have a `send(from, to)` function, and `from` should always be the same for our task, we can get a partial and go on with it. pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy