Skip to content

Function binding #229

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Feb 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
The answer: `null`.
Risposta: `null`.


```js run
Expand All @@ -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.
Il contesto di una funzione associata è fisso. Non esiste alcun modo di cambiarlo successivamente.

So even while we run `user.g()`, the original function is called with `this=null`.
Quindi, anche se eseguiamo `user.g()`, la funzione originale verrà chiamata con `this=null`.
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ importance: 5

---

# Bound function as a method
# Funzione associata come metodo

What will be the output?
Quale sarà l'output?

```js
function f() {
Expand Down
6 changes: 3 additions & 3 deletions 1-js/06-advanced-functions/10-bind/3-second-bind/solution.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
The answer: **John**.
Risposta: **John**.

```js run no-beautify
function f() {
Expand All @@ -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.
L' *exotic object* [bound function](https://tc39.github.io/ecma262/#sec-bound-function-exotic-objects) restituito da `f.bind(...)` memorizza il contesto (e gli argomenti, se forniti) solo in fase di creazione.

A function cannot be re-bound.
Una funzione non può essere riassegnata.
7 changes: 3 additions & 4 deletions 1-js/06-advanced-functions/10-bind/3-second-bind/task.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ importance: 5

---

# Second bind
# Secondo bind

Can we change `this` by additional binding?
Possiamo cambiare `this` con una associazione addizionale?

What will be the output?
Quale sarà l'output?

```js no-beautify
function f() {
Expand All @@ -17,4 +17,3 @@ f = f.bind( {name: "John"} ).bind( {name: "Ann" } );

f();
```

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
The answer: `undefined`.
Risposta: `undefined`.

The result of `bind` is another object. It does not have the `test` property.
Il risultato di `bind` è un altro oggetto, che non ha la proprietà `test`.

Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ importance: 5

---

# Function property after bind
# Proprietà della funzione dopo il bind

There's a value in the property of a function. Will it change after `bind`? Why, or why not?
C'è un valore nella proprietà di una funzione. Cambierà dopo `bind`? Perché, o perché no?

```js run
function sayHi() {
Expand All @@ -17,7 +17,7 @@ let bound = sayHi.bind({
name: "John"
});

alert( bound.test ); // what will be the output? why?
alert( bound.test ); // quale sarà l'output? Perché?
*/!*
```

Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@

The error occurs because `ask` gets functions `loginOk/loginFail` without the object.
L'errore si verifica perché `askPassword` riceve le funzioni `loginOk/loginFail` senza l'oggetto.

When it calls them, they naturally assume `this=undefined`.
Quando le chiamiamo, naturalmente assumono `this=undefined`.

Let's `bind` the context:
Usiamo `bind` per associare il contesto:

```js run
function askPassword(ok, fail) {
Expand All @@ -30,14 +30,14 @@ askPassword(user.loginOk.bind(user), user.loginFail.bind(user));
*/!*
```

Now it works.
Ora funziona.

An alternative solution could be:
Una soluzione alternativa potrebbe essere:
```js
//...
askPassword(() => user.loginOk(), () => user.loginFail());
```

Usually that also works and looks good.
Di solito anche questo funziona e appare come una buona soluzione.

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()`.
Tuttavia è un po' meno affidabile in situazioni più complesse, in cui la variabile `user` potrebbe cambiare *dopo* la chiamata di `askPassword`, ma *prima* che il visitatore risponda e venga chiamata `() => user.loginOk()`.
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ importance: 5

---

# Fix a function that loses "this"
# Correggi una funzione che ha perso "this"

The call to `askPassword()` in the code below should check the password and then call `user.loginOk/loginFail` depending on the answer.
La chiamata di `askPassword()` nel codice sottostante dovrebbe controllare la password e quindi chiamare `user.loginOk/loginFail` a seconda della risposta.

But it leads to an error. Why?
Ma porta a un errore. Perché?

Fix the highlighted line for everything to start working right (other lines are not to be changed).
Correggi la riga evidenziata affinché tutto funzioni correttamente (le altre righe non devono essere modificate).

```js run
function askPassword(ok, fail) {
Expand Down
6 changes: 3 additions & 3 deletions 1-js/06-advanced-functions/10-bind/6-ask-partial/solution.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@


1. Either use a wrapper function, an arrow to be concise:
1. Puoi sia utilizzare una funzione wrapper, che una arrow per essere concisi:

```js
askPassword(() => user.login(true), () => user.login(false));
```

Now it gets `user` from outer variables and runs it the normal way.
Ora riceve `user` dalla variabile esterna ed esegue la funzione in maniera corretta.

2. Or create a partial function from `user.login` that uses `user` as the context and has the correct first argument:
2. Oppure creare una funzione parziale da `user.login` che utilizzi `user` come contesto ed abbia il giusto primo argomento:


```js
Expand Down
11 changes: 5 additions & 6 deletions 1-js/06-advanced-functions/10-bind/6-ask-partial/task.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ importance: 5

---

# Partial application for login
# Applicazione parziale per login

The task is a little more complex variant of <info:task/question-use-bind>.
Il compito è una variante leggermente più complessa di <info:task/question-use-bind>.

The `user` object was modified. Now instead of two functions `loginOk/loginFail`, it has a single function `user.login(true/false)`.
L'oggetto `user` è stato modificato. Ora al posto delle due funzioni `loginOk/loginFail`, ha una sola funzione `user.login(true/false)`.

What should we pass `askPassword` in the code below, so that it calls `user.login(true)` as `ok` and `user.login(false)` as `fail`?
Cosa dovremmo passare a `askPassword` nel codice qui sotto, in modo che chiami `user.login(true)` come `ok` e `user.login(false)` come `fail`?

```js
function askPassword(ok, fail) {
Expand All @@ -30,5 +30,4 @@ askPassword(?, ?); // ?
*/!*
```

Your changes should only modify the highlighted fragment.

Le tue modifiche dovrebbero solo interessare la porzione di codice evidenziata.
Loading