From 70d8d94386bd521918a8ee37b0cd01c00b110c1b Mon Sep 17 00:00:00 2001 From: vplentinax Date: Sun, 24 May 2020 21:25:03 -0400 Subject: [PATCH 1/2] bind --- .../2-write-to-object-after-bind/solution.md | 6 +- .../2-write-to-object-after-bind/task.md | 4 +- .../10-bind/3-second-bind/solution.md | 6 +- .../10-bind/3-second-bind/task.md | 6 +- .../solution.md | 4 +- .../4-function-property-after-bind/task.md | 6 +- .../10-bind/5-question-use-bind/solution.md | 13 +- .../10-bind/5-question-use-bind/task.md | 10 +- .../10-bind/6-ask-partial/solution.md | 16 ++ .../10-bind/6-ask-partial/task.md | 34 +++ 1-js/06-advanced-functions/10-bind/article.md | 211 ++++++++++++++---- 11 files changed, 245 insertions(+), 71 deletions(-) create mode 100644 1-js/06-advanced-functions/10-bind/6-ask-partial/solution.md create mode 100644 1-js/06-advanced-functions/10-bind/6-ask-partial/task.md 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 8cd18ec56..a9999368a 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,9 @@ 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, elaborate? +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 +17,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 0cb673b12..92acf4651 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,15 @@ 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, but may fail in more complex situations where `user` has a chance of being overwritten between the moments of asking and running `() => user.loginOk()`. +Por lo general, eso también funciona y se ve bien. +Es un poco menos confiable, aunque en situaciones más complejas donde la variable `user` podría cambiar *después* de que se llama a `askPassword`, pero *antes* el visitante responde y llama a `() => 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 eb19e6644..e11265df5 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,13 @@ importance: 5 --- -# Ask losing this +# Arreglar una función que perdió "this" -The call to `askPassword()` in the code below should check the password and then call `user.loginOk/loginFail` depending on the answer. +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. -But it leads to an error. Why? +Pero lleva a un error. ¿Por qué? -Fix the highlighted line for everything to start working right (other lines are not to be changed). +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) { @@ -34,5 +34,3 @@ let user = { askPassword(user.loginOk, user.loginFail); */!* ``` - - 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 new file mode 100644 index 000000000..0e501dc69 --- /dev/null +++ b/1-js/06-advanced-functions/10-bind/6-ask-partial/solution.md @@ -0,0 +1,16 @@ + + +1. Utilice una función de contenedor, una flecha para ser conciso: + + ```js + askPassword(() => user.login(true), () => user.login(false)); + ``` + + 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 + askPassword(user.login.bind(user, true), user.login.bind(user, false)); + ``` 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 new file mode 100644 index 000000000..0550efb7e --- /dev/null +++ b/1-js/06-advanced-functions/10-bind/6-ask-partial/task.md @@ -0,0 +1,34 @@ +importance: 5 + +--- + +# Aplicación parcial para inicio de sesión + +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`? + +```js +function askPassword(ok, fail) { + let password = prompt("Password?", ''); + if (password == "rockstar") ok(); + else fail(); +} + +let user = { + name: 'John', + + login(result) { + alert( this.name + (result ? ' logged in' : ' failed to log in') ); + } +}; + +*!* +askPassword(?, ?); // ? +*/!* +``` + +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 fdb07c608..fc0bcf6b6 100644 --- a/1-js/06-advanced-functions/10-bind/article.md +++ b/1-js/06-advanced-functions/10-bind/article.md @@ -3,17 +3,17 @@ libs: --- -# Function binding +# Función vinculadora -When using `setTimeout` with object methods or passing object methods along, there's a known problem: "losing `this`". +Al pasar métodos de objeto como devoluciones de llamada, por ejemplo a `setTimeout`, genera un problema conocido: "pérdida de `this`". -Suddenly, `this` just stops working right. The situation is typical for novice developers, but happens with experienced ones as well. +En este capítulo veremos las formas de solucionarlo. -## Losing "this" +## Pérdida de "this" -We already know that in JavaScript it's easy to lose `this`. Once a method is passed somewhere separately from the object -- `this` is lost. +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. -Here's how it may happen with `setTimeout`: +Así es como puede suceder con `setTimeout`: ```js run let user = { @@ -28,22 +28,22 @@ 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 as we'll see, usually `this` just becomes `undefined`. +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`. -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? +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? -## Solution 1: a wrapper +## Solución 1: un contenedor o envoltura -The simplest solution is to use a wrapping function: +La solución más simple es usar una función de envoltura: ```js run let user = { @@ -60,17 +60,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,30 +83,32 @@ let user = { setTimeout(() => user.sayHi(), 1000); -// ...within 1 second -user = { sayHi() { alert("Another user in setTimeout!"); } }; +// ...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 be 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 una función especial "objeto exótico" 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 = { @@ -123,9 +125,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 = { @@ -136,15 +138,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 @@ -159,14 +161,21 @@ let user = { let sayHi = user.sayHi.bind(user); // (*) */!* +// puede ejecutarlo sin un objeto sayHi(); // Hello, John! setTimeout(sayHi, 1000); // Hello, John! + +// 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 "enlazada", que se puede llamar sola o pasarse 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 = { @@ -178,12 +187,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) { @@ -193,11 +202,127 @@ 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. ```` -## Summary +## Funciones parciales + +Hasta ahora solo hemos estado hablando de vincular `this`. Vamos un paso más allá. + +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`: + +```js +let bound = func.bind(context, [arg1], [arg2], ...); +``` + +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) { + return a * b; +} +``` + +Usemos `bind` para crear una función` double` en su base: + +```js run +function mul(a, b) { + return a * b; +} + +*!* +let double = mul.bind(null, 2); +*/!* + +alert( double(3) ); // = mul(2, 3) = 6 +alert( double(4) ); // = mul(2, 4) = 8 +alert( double(5) ); // = mul(2, 5) = 10 +``` + +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`. + +La función `triple` en el siguiente código triplica el valor: + +```js run +function mul(a, b) { + return a * b; +} + +*!* +let triple = mul.bind(null, 3); +*/!* + +alert( triple(3) ); // = mul(3, 3) = 9 +alert( triple(4) ); // = mul(3, 4) = 12 +alert( triple(5) ); // = mul(3, 5) = 15 +``` + +¿Por qué solemos hacer una función parcial? + +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`. + +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. + +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. + +## Parcial sin contexto + +¿Qué pasa si nos gustaría arreglar algunos argumentos, pero no el contexto `this`? Por ejemplo, para un método de objeto. + +El método `bind` nativo no permite eso. No podemos simplemente omitir el contexto y saltar a los argumentos. + +Afortunadamente, se puede implementar fácilmente una función `parcial` para vincular solo argumentos. + +Cómo esto: + +```js run +*!* +function partial(func, ...argsBound) { + return function(...args) { // (*) + return func.call(this, ...argsBound, ...args); + } +} +*/!* + +// Uso: +let user = { + firstName: "John", + say(time, phrase) { + alert(`[${time}] ${this.firstName}: ${phrase}!`); + } +}; + +// agregar un método parcial con tiempo fijo +user.sayNow = partial(user.say, new Date().getHours() + ':' + new Date().getMinutes()); + +user.sayNow("Hello"); +// Algo como: +// [10:00] John: 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 + +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. + +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`. -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` in an object method, so that we can pass it somewhere. For example, to `setTimeout`. There are more reasons to `bind` in the modern development, we'll meet them later. +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. From d8070d3d0f053279d8443c70eb4451b425fc0e96 Mon Sep 17 00:00:00 2001 From: vplentinax Date: Mon, 1 Jun 2020 21:03:38 -0400 Subject: [PATCH 2/2] corrections --- .../10-bind/5-question-use-bind/solution.md | 2 +- .../10-bind/6-ask-partial/solution.md | 2 +- 1-js/06-advanced-functions/10-bind/article.md | 16 ++++++++-------- 3 files changed, 10 insertions(+), 10 deletions(-) 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 92acf4651..ad4ffa67e 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 @@ -40,5 +40,5 @@ askPassword(() => user.loginOk(), () => user.loginFail()); Por lo general, eso también funciona y se ve bien. -Es un poco menos confiable, aunque en situaciones más complejas donde la variable `user` podría cambiar *después* de que se llama a `askPassword`, pero *antes* el visitante responde y llama a `() => user.loginOk ()`. +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 ()`. 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 0e501dc69..cc8fd21ce 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,6 +1,6 @@ -1. Utilice una función de contenedor, una flecha para ser conciso: +1. Utilice una función wrapper (envoltura), de tipo arrow (flecha) para ser conciso: ```js askPassword(() => user.login(true), () => user.login(false)); diff --git a/1-js/06-advanced-functions/10-bind/article.md b/1-js/06-advanced-functions/10-bind/article.md index fc0bcf6b6..51288dd32 100644 --- a/1-js/06-advanced-functions/10-bind/article.md +++ b/1-js/06-advanced-functions/10-bind/article.md @@ -3,9 +3,9 @@ libs: --- -# Función vinculadora +# Función binding (vinculadora) -Al pasar métodos de objeto como devoluciones de llamada, por ejemplo a `setTimeout`, genera un problema conocido: "pérdida de `this`". +Al pasar métodos de objeto como devoluciones de llamada, por ejemplo a `setTimeout`, se genera un problema conocido: "pérdida de `this`". En este capítulo veremos las formas de solucionarlo. @@ -41,9 +41,9 @@ El método `setTimeout` en el navegador es un poco especial: establece `this = w 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 contenedor o envoltura +## Solución 1: un wrapper (envoltura) -La solución más simple es usar una función de envoltura: +La solución más simple es usar una función wrapper (envoltura): ```js run let user = { @@ -104,7 +104,7 @@ La sintaxis básica es: let boundFunc = func.bind(context); ``` -El resultado de `func.bind(context)` es una función especial "objeto exótico" 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`. +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`. En otras palabras, llamar a `boundFunc` es como `func` con un `this` fijo. @@ -173,7 +173,7 @@ user = { }; ``` -En la línea `(*)` tomamos el método `user.sayHi` y lo vinculamos a `user`. `sayHi` es una función "enlazada", que se puede llamar sola o pasarse en `setTimeout` -- no importa, el contexto será el correcto. +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. Aquí podemos ver que los argumentos se pasan "tal cual", solo que `this` se fija mediante` bind`: @@ -275,13 +275,13 @@ Por ejemplo, tenemos una función `send(from, to, text)`. Luego, dentro de un ob ## Parcial sin contexto -¿Qué pasa si nos gustaría arreglar algunos argumentos, pero no el contexto `this`? Por ejemplo, para un método de objeto. +¿Qué pasa si nos gustaría fijar algunos argumentos, pero no el contexto `this`? Por ejemplo, para un método de objeto. El método `bind` nativo no permite eso. No podemos simplemente omitir el contexto y saltar a los argumentos. Afortunadamente, se puede implementar fácilmente una función `parcial` para vincular solo argumentos. -Cómo esto: +Como esto: ```js run *!* 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