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
As we can see, the output shows not "John" as`this.firstName`, but`undefined`!
31
+
Comme nous pouvons le voir, la sortie n'affiche pas "John" pour`this.firstName`, mais`undefined`!
32
32
33
-
That's because`setTimeout`got the function `user.sayHi`, separately from the object. The last line can be rewritten as:
33
+
C'est car`setTimeout`a eu la fonction `user.sayHi`, séparement de l'objet. La dernière ligne pourrait être réécrite comme :
34
34
35
35
```js
36
36
let f =user.sayHi;
37
-
setTimeout(f, 1000); //lost user context
37
+
setTimeout(f, 1000); //Perte du contexte d'user
38
38
```
39
39
40
-
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`.
40
+
La méthode`setTimeout`dans le navigateur est un peu spéciale : elle définit`this=window`pour l'appel à la fonction (pour Node.js, `this`devient un objet "timer", mais ça n'a pas d'importance ici). Donc pour`this.firstName`il essaye de récuperer`window.firstName`, qui n'existe pas. Dans d'autres cas similaires, `this`devient généralement`undefined`.
41
41
42
-
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?
42
+
Cette tâche est plutôt commune -- on veut transmettre une méthode objet quelque part ailleurs (ici -- au scheduler) où elle sera appelée.
43
+
Comment s'assurer qu'elle sera appelée dans le bon contexte ?
43
44
44
-
## Solution 1: a wrapper
45
+
## Solution 1 : Un wrapper
45
46
46
-
The simplest solution is to use a wrapping function:
47
+
La solution la plus simple est d'utiliser une fonction enveloppée :
47
48
48
49
```js run
49
50
let user = {
@@ -60,18 +61,17 @@ setTimeout(function() {
60
61
*/!*
61
62
```
62
63
63
-
Now it works, because it receives`user`from the outer lexical environment, and then calls the method normally.
64
+
Maintenant ça fonctionne, car elle reçoit`user`depuis un environnement lexical extérieur, et donc les appels à la fonction se font normalement.
Looks fine, but a slight vulnerability appears in our code structure.
72
-
73
-
What if before `setTimeout` triggers (there's one second delay!) `user` changes value? Then, suddenly, it will call the wrong object!
72
+
Ça à l'air bon, mais une légère vulnérabilité apparaît dans la structure de notre code.
74
73
74
+
Que se passe t-il si avant le déclenchement de `setTimeout` (il y une seconde de délai) `user` changeait de valeur ? Alors, soudainement, ça appelera le mauvais objet !
75
75
76
76
```js run
77
77
let user = {
@@ -83,32 +83,32 @@ let user = {
83
83
84
84
setTimeout(() =>user.sayHi(), 1000);
85
85
86
-
// ...the value of user changes within 1 second
86
+
// ...La valeur d'user dans 1 seconde
87
87
user = {
88
88
sayHi() { alert("Another user in setTimeout!"); }
89
89
};
90
90
91
-
//Another user in setTimeout!
91
+
//Un autre user est dans le setTimeout!
92
92
```
93
93
94
-
The next solution guarantees that such thing won't happen.
94
+
La prochaine solution garantit que ce genre de chose n'arrivera pas
95
95
96
-
## Solution 2: bind
96
+
## Solution 2 : "bind"
97
97
98
-
Functions provide a built-in method [bind](mdn:js/Function/bind)that allows to fix`this`.
98
+
Les fonctions fournissent une méthode intégrée, [bind](mdn:js/Function/bind)qui permet de corriger`this`.
99
99
100
-
The basic syntax is:
100
+
La syntaxe basique est :
101
101
102
102
```js
103
-
//more complex syntax will come a little later
103
+
//Une syntaxe plus complexe arrivera bientot
104
104
let boundFunc =func.bind(context);
105
105
```
106
106
107
-
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`.
107
+
Le résultat de`func.bind(context)`est une "objet exotique" dans le style d'une fonction, qui est appellable comme une fonction et qui transmet l'appel à`func`en définissant `this=context` de façon transparente.
108
108
109
-
In other words, calling`boundFunc`is like`func`with fixed`this`.
109
+
En d'autres termes, appeller`boundFunc`équivaut à`func`avec un`this` corrigé.
110
110
111
-
For instance, here`funcUser`passes a call to `func` with `this=user`:
111
+
Par exemple, ici`funcUser`passe l'appel à `this` tel que `this=user`:
112
112
113
113
```js run
114
114
let user = {
@@ -125,9 +125,9 @@ funcUser(); // John
125
125
*/!*
126
126
```
127
127
128
-
Here`func.bind(user)`as a "bound variant" of`func`, with fixed`this=user`.
128
+
Ici`func.bind(user)`en tant "variante liée" de`func`, avec`this=user`.
129
129
130
-
All arguments are passed to the original `func` "as is", for instance:
130
+
Tous les arguments sont passés à l'originale `func` "tels quels", par exemple :
131
131
132
132
```js run
133
133
let user = {
@@ -138,15 +138,15 @@ function func(phrase) {
138
138
alert(phrase +', '+this.firstName);
139
139
}
140
140
141
-
//bind this to user
141
+
//Lie this à user
142
142
let funcUser =func.bind(user);
143
143
144
144
*!*
145
-
funcUser("Hello"); // Hello, John (argument "Hello" is passed, and this=user)
145
+
funcUser("Hello"); // Hello, John (l'argument "Hello" est passé, et this=user)
146
146
*/!*
147
147
```
148
148
149
-
Now let's try with an object method:
149
+
Maintenant essayons avec une méthode objet :
150
150
151
151
152
152
```js run
@@ -161,21 +161,21 @@ let user = {
161
161
let sayHi =user.sayHi.bind(user); // (*)
162
162
*/!*
163
163
164
-
//can run it without an object
164
+
//Peut s'exécuter sans objet
165
165
sayHi(); // Hello, John!
166
166
167
167
setTimeout(sayHi, 1000); // Hello, John!
168
168
169
-
//even if the value of user changes within 1 second
170
-
// sayHi uses the pre-bound value which is reference to the old user object
169
+
//Mème si la valeur de user change dans 1 seconde
170
+
// sayHi utilise la valeur pré-liée, laquelle fait référence à l'ancien objet user
171
171
user = {
172
172
sayHi() { alert("Another user in setTimeout!"); }
173
173
};
174
174
```
175
175
176
-
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.
176
+
Sur la ligne`(*)`nous prenons la méthode`user.sayHi`en nous la lions à `user`. La méthode `sayHi`est une fonction "liée", qui peut être appelée seule ou être transmise à `setTimeout` -- ça n'a pas d'importance, le contexte sera le bon.
177
177
178
-
Here we can see that arguments are passed "as is", only`this`is fixed by`bind`:
178
+
Ici, nous pouvons voir que les arguments passés "tels quels", seulement`this`est corrigé par`bind`:
179
179
180
180
```js run
181
181
let user = {
@@ -187,12 +187,12 @@ let user = {
187
187
188
188
let say =user.say.bind(user);
189
189
190
-
say("Hello"); // Hello, John! ("Hello" argument is passed to say)
191
-
say("Bye"); // Bye, John! ("Bye" is passed to say)
190
+
say("Hello"); // Hello, John! (l'argument "Hello" est passé à say)
191
+
say("Bye"); // Bye, John! (l'argument "Bye" est passé à say)
192
192
```
193
193
194
-
````smart header="Convenience method: `bindAll`"
195
-
If an object has many methods and we plan to actively pass it around, then we could bind them all in a loop:
Si un objet a plusieurs méthodes et que nous prévoyons de le transmettre plusieurs fois, alors on pourrait toutes les lier dans une boucle :
196
196
197
197
```js
198
198
for (let key in user) {
@@ -202,32 +202,32 @@ for (let key in user) {
202
202
}
203
203
```
204
204
205
-
JavaScript libraries also provide functions for convenient mass binding , e.g. [_.bindAll(object, methodNames)](https://lodash.com/docs#bindAll)in lodash.
205
+
Les librairies JavaScript fournissent aussi des fonctions pratiques pour les liaisons de masse, e.g. [_.bindAll(object, methodNames)](https://lodash.com/docs#bindAll)avec lodash.
206
206
````
207
207
208
-
## Partial functions
208
+
## Les fonctions partielles
209
209
210
-
Until now we have only been talking about binding `this`. Let's take it a step further.
210
+
Jusqu'à maintenant nous avons parlé uniquement de lier `this`. Allons plus loin.
211
211
212
-
We can bind not only `this`, but also arguments. That's rarely done, but sometimes can be handy.
212
+
Nous pouvons lier `this`, mais aussi des arguments. C'est rarement utilisé, mais ça peut être pratique.
213
213
214
-
The full syntax of `bind`:
214
+
La syntaxe complète de `bind`:
215
215
216
216
```js
217
217
let bound = func.bind(context, [arg1], [arg2], ...);
218
218
```
219
219
220
-
It allows to bind context as `this` and starting arguments of the function.
220
+
Elle permet de lier le contexte en tant que `this` et de démarrer les arguments de la fonction.
221
221
222
-
For instance, we have a multiplication function `mul(a, b)`:
222
+
Par exemple, nous avons une fonction de multiplication `mul(a, b)`:
223
223
224
224
```js
225
225
function mul(a, b) {
226
226
return a * b;
227
227
}
228
228
```
229
229
230
-
Let's use `bind` to create a function `double` on its base:
230
+
Utilisons `bind` pour créer une fonction `double` sur cette base:
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".
246
+
L'appel à `mul.bind(null, 2)` créer une nouvelle fonction `double` qui transmet les appels à `mul`, corrigeant `null` dans le contexte et `2` comme premier argument. Les arguments sont passés "tels quels" plus loin.
247
247
248
-
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.
248
+
Ça s'appelle [l'application de fonction partielle](https://en.wikipedia.org/wiki/Partial_application) -- nous créeons une nouvelle fonction en corrigeant certains paramètres d'une fonction existante.
249
249
250
-
Please note that we actually don't use `this` here. But `bind` requires it, so we must put in something like `null`.
250
+
Veuillez noter que nous n'utilisons actuellement pas `this` ici. Mais `bind` en a besoin, donc nous devrions mettre quelque chose dedans comme `null`.
251
251
252
-
The function `triple` in the code below triples the value:
252
+
La fonction `triple` dans le code ci-dessous triple la valeur :
Pourquoi faisons nous généralement une fonction partielle ?
269
269
270
-
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`.
270
+
L'avantage de faire ça est que nous pouvons créer une fonction indépendante avec un nom lisible (`double`, `triple`). Nous pouvons les utiliser et ne pas fournir de premier argument à chaque fois puisque c'est corrigé par `bind`.
271
271
272
-
In other cases, partial application is useful when we have a very generic function and want a less universal variant of it for convenience.
272
+
Dans d'autres cas, les fonctions partielles sont utiles quand nous avons des fonctions vraiment génériques et que nous voulons une variante moins universelle pour des raisons pratiques.
273
273
274
-
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.
274
+
Par exemple, nous avons une fonction `send(from, to, text)`. Alors, dans un objet `user` nous pourrions vouloir en utiliser une variante partielle : `sendTo(to, text)` qui envoie depuis l'utilisateur actuel.
275
275
276
-
## Going partial without context
276
+
## Aller dans les partielles sans contexte
277
277
278
-
What if we'd like to fix some arguments, but not the context `this`? For example, for an object method.
278
+
Que se passerait t-il si nous voulions corriger certains arguments, mais pas le contexte `this` ?
279
+
Par exemple, pour une méthode objet.
279
280
280
-
The native `bind` does not allow that. We can't just omit the context and jump to arguments.
281
+
La fonction `bind` native ne permet pas ça. Nous ne pouvons pas juste omettre le contexte et aller directement aux arguments.
281
282
282
-
Fortunately, a function `partial` for binding only arguments can be easily implemented.
283
+
Heureusement, une fonction `partial` pour lier seulement les arguments peut être facilement implémentée.
283
284
284
-
Like this:
285
+
Comme ça :
285
286
286
287
```js run
287
288
*!*
@@ -292,37 +293,37 @@ function partial(func, ...argsBound) {
292
293
}
293
294
*/!*
294
295
295
-
// Usage:
296
+
// Utilisation :
296
297
let user = {
297
298
firstName: "John",
298
299
say(time, phrase) {
299
300
alert(`[${time}] ${this.firstName}: ${phrase}!`);
300
301
}
301
302
};
302
303
303
-
// add a partial method with fixed time
304
+
// Ajoute une méthode partielle avec time corrigé
304
305
user.sayNow = partial(user.say, new Date().getHours() + ':' + new Date().getMinutes());
305
306
306
307
user.sayNow("Hello");
307
-
// Something like:
308
+
// Quelque chose du genre :
308
309
// [10:00] John: Hello!
309
310
```
310
311
311
-
The result of `partial(func[, arg1, arg2...])` call is a wrapper `(*)` that calls `func` with:
312
-
- Same `this` as it gets (for `user.sayNow` call it's `user`)
313
-
- Then gives it `...argsBound` -- arguments from the `partial` call (`"10:00"`)
314
-
- Then gives it `...args` -- arguments given to the wrapper (`"Hello"`)
312
+
Le résultat de l'appel `partial(func[, arg1, arg2...])` est une enveloppe `(*)` qui appelle `func` avec :
313
+
- Le même `this` qu'il récupère (pour `user.sayNow` l'appel est `user`)
314
+
- Alors il donne `...argsBound` -- les arguments provenant de l'appel de `partial` (`"10:00"`)
315
+
- Alors il donne `...args` -- les arguments donnés à l'enveloppe (`"Hello"`)
315
316
316
-
So easy to do it with the spread syntax, right?
317
+
Alors, c'est simple à faire avec la spread syntaxe, pas vrai ?
317
318
318
-
Also there's a ready [_.partial](https://lodash.com/docs#partial) implementation from lodash library.
319
+
Aussi il y a une implémentation de [_.partial](https://lodash.com/docs#partial) prête à l'emploi dans les librairies lodash.
319
320
320
-
## Summary
321
+
## Résumé
321
322
322
-
Method `func.bind(context, ...args)` returns a "bound variant" of function `func` that fixes the context `this` and first arguments if given.
323
+
La méthode `func.bind(context, ...args)` retourne une "variante liée" de la fonction `func` qui corrige le contexte de `this` et des premiers arguments s'ils sont donnés.
323
324
324
-
Usually we apply `bind` to fix `this` for an object method, so that we can pass it somewhere. For example, to `setTimeout`.
325
+
Nous appliquons généralement `bind` pour corriger `this` pour une méthode objet, comme ça nous pouvons la passer ailleurs. Par exemple, à `setTimeout`.
325
326
326
-
When we fix some arguments of an existing function, the resulting (less universal) function is called *partially applied* or *partial*.
327
+
Quand nous corrigeons certains arguments d'une fonction existante, la fonction (moins universelle) en résultant est dite *partiellement appliquée* ou *partielle*.
327
328
328
-
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.
329
+
Les fonctions partielles sont pratiques quand nous ne voulons pas répéter le même argument encore et encore. Comme si nous avions une fonction `send(from, to)`, et que `from` devait être toujours le même pour notre tâche, nous pourrions récupérer une partielle et continuer.
0 commit comments