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/06-function-object/article.md
+36-37Lines changed: 36 additions & 37 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,17 +3,15 @@
3
3
4
4
Comme nous le savons déjà, une fonction en JavaScript est une valeur.
5
5
6
-
Chaque valeur en JavaScript a un type. Quel type est une fonction?
6
+
Chaque valeur en JavaScript a un type. De quel type est une fonction?
7
7
8
8
Pour JavaScript, les fonctions sont des objets.
9
9
10
-
Un bon moyen d’imaginer des fonctions est en tant que des "objets d’action" qu'on peut appeler. Nous pouvons non seulement les appeler, mais aussi les traiter comme des objets: ajouter/supprimer des propriétés, passer par référence, etc.
10
+
Un bon moyen d’imaginer des fonctions est en tant que des "objets d’action" qu'on peut appeler. Nous pouvons non seulement les appeler, mais aussi les traiter comme des objets: ajouter/supprimer des propriétés, passer par référence, etc.
11
11
12
12
## La propriété "name"
13
13
14
-
Les objets Function contiennent quelques propriétés utilisables.
15
-
16
-
Les objets fonction contiennent des propriétés utilisables.
14
+
Les objets Fonction contiennent des propriétés utilisables.
17
15
18
16
Par exemple, le nom d'une fonction est accessible en tant que propriété "name" :
19
17
@@ -32,22 +30,22 @@ let sayHi = function() {
32
30
alert("Hi");
33
31
};
34
32
35
-
alert(sayHi.name); // sayHi (il y a un nom!)
33
+
alert(sayHi.name); // sayHi (il y a un nom!)
36
34
```
37
35
38
-
Cela fonctionne aussi si l’affectation est faite avec une valeur par défaut:
36
+
Cela fonctionne aussi si l’affectation est faite avec une valeur par défaut:
39
37
40
38
```js run
41
39
functionf(sayHi=function() {}) {
42
-
alert(sayHi.name); // sayHi (ça marche!)
40
+
alert(sayHi.name); // sayHi (ça marche!)
43
41
}
44
42
45
43
f();
46
44
```
47
45
48
-
Dans la spécification, cette fonctionnalité est appelée "contextual name". Si la fonction n'en fournit pas, alors dans l'affectation elle est extraite du contexte.
46
+
Dans la spécification, cette fonctionnalité est appelée "contextual name". Si la fonction n'en fournit pas, elle est déterminée à partir du contexte lors de l'affectation.
Cependant c'est pas magique. Il y a des cas où il n'y a aucun moyen de trouver le bon nom. Dans ce cas, la propriété name est vide, comme ci-dessous:
67
+
Cependant c'est pas magique. Il y a des cas où il n'y a aucun moyen de trouver le bon nom. Dans ce cas, la propriété name est vide, comme ci-dessous:
70
68
71
69
```js
72
70
// fonction créée dans un tableau
@@ -80,7 +78,7 @@ Par contre, en pratique la plupart des fonctions ont un nom.
80
78
81
79
## La propriété "length"
82
80
83
-
Il existe une autre propriété native, "length", qui renvoie le nombre de paramètres de la fonction, par exemple:
81
+
Il existe une autre propriété native, "length", qui renvoie le nombre de paramètres de la fonction, par exemple:
84
82
85
83
```js run
86
84
functionf1(a) {}
@@ -98,7 +96,7 @@ La propriété `length` est parfois utilisée pour la [réfléxion (introspectio
98
96
99
97
Par exemple, dans le code ci-dessous, la fonction `ask` accepte une `question` à poser et un nombre arbitraire de fonctions `handler` (gestionnaires) à appeler.
100
98
101
-
Une fois qu'un utilisateur a fourni sa réponse, la fonction appelle les gestionnaires. Nous pouvons transmettre deux types de gestionnaires:
99
+
Une fois qu'un utilisateur a fourni sa réponse, la fonction appelle les gestionnaires. Nous pouvons transmettre deux types de gestionnaires:
102
100
103
101
- Une fonction sans argument, qui n'est appelée que lorsque l'utilisateur donne une réponse positive.
104
102
- Une fonction avec des arguments, appelée dans les deux cas et renvoyant une réponse.
@@ -122,17 +120,17 @@ function ask(question, ...handlers) {
122
120
}
123
121
124
122
// pour une réponse positive, les deux gestionnaires sont appelés
125
-
// pour réponse négative, seulement le second
123
+
// pour une réponse négative, seulement le second
126
124
ask("Question?", () =>alert('You said yes'), result=>alert(result));
127
125
```
128
126
129
-
Ceci est un cas particulier de ce qu'on appelle [polymorphism](https://en.wikipedia.org/wiki/Polymorphism_(computer_science)) -- le traitement des arguments différemment selon leur type ou, dans notre cas, en fonction de la `length`. L'idée a une utilisation dans les bibliothèques JavaScript.
127
+
Ceci est un cas particulier de ce qu'on appelle le [polymorphism](https://en.wikipedia.org/wiki/Polymorphism_(computer_science)) -- le traitement des arguments différemment selon leur type ou, dans notre cas, en fonction de la `length`. Cette approche est utilisée dans les bibliothèques JavaScript.
130
128
131
129
## Propriétés personnalisées
132
130
133
131
Nous pouvons également ajouter nos propres propriétés.
134
132
135
-
Nous ajoutons ici la propriété `counter` pour suivre le nombre total d'appels:
133
+
Nous ajoutons ici la propriété `counter` pour suivre le nombre total d'appels:
136
134
137
135
```js run
138
136
functionsayHi() {
@@ -156,11 +154,12 @@ Une propriété affectée à une fonction comme `sayHi.counter = 0` *ne définit
156
154
157
155
On peut traiter une fonction comme un objet, y stocker des propriétés, mais cela n’a aucun effet sur son exécution. Les variables ne sont pas des propriétés de fonction et inversement. Ce sont des mondes parallèles.
158
156
```
159
-
Les propriétés de fonction peuvent parfois remplacer les fermetures. Par exemple, nous pouvons réécrire l’exemple de fonction de compteur du chapitre <info:fermeture> pour utiliser une propriété de fonction:
157
+
158
+
Les propriétés de fonction peuvent parfois remplacer les fermetures. Par exemple, nous pouvons réécrire l’exemple de fonction de compteur du chapitre <info:closure> pour utiliser une propriété de fonction :
160
159
161
160
```js run
162
161
functionmakeCounter() {
163
-
// au lieu de:
162
+
// au lieu de:
164
163
// let count = 0
165
164
166
165
functioncounter() {
@@ -177,11 +176,11 @@ alert( counter() ); // 0
177
176
alert( counter() ); // 1
178
177
```
179
178
180
-
Le `count` est maintenant stocké dans la fonction directement, pas dans son environnement lexical externe
179
+
Le `count` est maintenant stocké dans la fonction directement, pas dans son environnement lexical externe.
181
180
182
-
Est-ce meilleur ou pire que d'utiliser une fermeture?
181
+
Est-ce meilleur ou pire que d'utiliser une fermeture?
183
182
184
-
La principale différence est que si la valeur de `count` réside dans une variable externe, le code externe ne peut pas y accéder. Seules les fonctions imbriquées peuvent le modifier. Et si c'est lié à une fonction, une telle chose est possible:
183
+
La principale différence est que si la valeur de `count` réside dans une variable externe, le code externe ne peut pas y accéder. Seules les fonctions imbriquées peuvent le modifier. Et si c'est lié à une fonction, une telle chose est possible:
185
184
186
185
```js run
187
186
functionmakeCounter() {
@@ -217,21 +216,21 @@ let sayHi = function(who) {
217
216
};
218
217
```
219
218
220
-
Et ajoutons un nom à cela:
219
+
Et ajoutons un nom à cela:
221
220
222
221
```js
223
222
letsayHi=function*!*func*/!*(who) {
224
223
alert(`Hello, ${who}`);
225
224
};
226
225
```
227
226
228
-
Avons-nous réalisé quelque chose ici? Quel est le but de ce nom supplémentaire `"func"`?
227
+
Avons-nous réalisé quelque chose ici? Quel est le but de ce nom supplémentaire `"func"`?
229
228
230
229
Notons d'abord que nous avons toujours une expression de fonction. L'ajout du nom `"func"` après `function` n'en a pas fait une déclaration de fonction, car il est toujours créé dans le cadre d'une expression d'affectation.
231
230
232
231
L'ajout d'un tel nom n'a également rien cassé.
233
232
234
-
La fonction est toujours disponible sous la forme `sayHi()`:
233
+
La fonction est toujours disponible sous la forme `sayHi()`:
235
234
236
235
```js run
237
236
letsayHi=function*!*func*/!*(who) {
@@ -241,12 +240,12 @@ let sayHi = function *!*func*/!*(who) {
241
240
sayHi("John"); // Hello, John
242
241
```
243
242
244
-
Il y a deux particularités à propos du nom `func`, voici les raisons :
243
+
Il y a deux particularités à propos du nom `func`, voici les raisons :
245
244
246
245
1. Il permet à la fonction de se référencer en interne.
247
246
2. Il n'est pas visible en dehors de la fonction.
248
247
249
-
Par exemple, la fonction `sayHi` ci-dessous s’appelle à nouveau avec `"Guest"` si aucun `who` est fourni:
248
+
Par exemple, la fonction `sayHi` ci-dessous s’appelle à nouveau avec `"Guest"` si aucun `who` est fourni:
250
249
251
250
```js run
252
251
letsayHi=function*!*func*/!*(who) {
@@ -261,14 +260,13 @@ let sayHi = function *!*func*/!*(who) {
261
260
262
261
sayHi(); // Hello, Guest
263
262
264
-
// Mais ceci ne marchera pas:
263
+
// Mais ceci ne marchera pas:
265
264
func(); // Error, func is not defined (pas visible à l'extérieur de la fonction)
266
265
```
267
266
268
-
Pourquoi utilisons-nous `func`? Peut-être juste utiliser `sayHi` pour l'appel imbriqué?
welcome(); // Error, l'appel sayHi imbriqué ne fonctionne plus!
299
+
welcome(); // Error, l'appel sayHi imbriqué ne fonctionne plus!
302
300
```
303
301
304
-
Cela se produit parce que la fonction tire `sayHi` de son environnement lexical externe. Il n'y a pas de `sayHi` local, donc la variable externe est utilisée. Et au moment de l'appel, cet`sayHi` extérieur est `null`.
302
+
Cela se produit parce que la fonction tire `sayHi` de son environnement lexical externe. Il n'y a pas de `sayHi` local, donc la variable externe est utilisée. Et au moment de l'appel, ce`sayHi` extérieur est `null`.
305
303
306
304
Le nom optionnel que nous pouvons mettre dans l’expression de fonction est destiné à résoudre exactement ce type de problèmes.
307
305
308
-
Utilisons-le pour corriger notre code:
306
+
Utilisons-le pour corriger notre code:
309
307
310
308
```js run
311
309
letsayHi=function*!*func*/!*(who) {
@@ -331,21 +329,22 @@ Le code externe a toujours sa variable `sayHi` ou `welcome`. Et `func` est un "n
331
329
```smart header="Il n'y a rien de tel pour la déclaration de fonction"
332
330
La fonctionnalité "nom interne" décrite ici n'est disponible que pour les expressions de fonction, pas pour les déclarations de fonction. Pour les déclarations de fonctions, il n’y a aucune possibilité de syntaxe d’ajouter un nom "interne" supplémentaire.
333
331
334
-
Parfois, lorsque nous avons besoin d’un nom interne fiable, c’est la raison pour laquelle nous réécrivons une déclaration de fonction en tant qe'expression de fonction nommée.
332
+
Parfois, lorsque nous avons besoin d’un nom interne fiable, c’est la raison pour laquelle nous réécrivons une déclaration de fonction en tant qu'expression de fonction nommée.
335
333
```
336
334
337
335
## Résumé
338
336
339
337
Les fonctions sont des objets.
340
338
341
-
Ici nous avons couvert leurs propriétés:
339
+
Ici nous avons couvert leurs propriétés:
342
340
343
341
-`name` - le nom de la fonction. Habituellement tiré de la définition de la fonction, mais s’il n’en existe pas, JavaScript essaie de le deviner à partir du contexte (par exemple, une affectation).
344
342
-`length` - le nombre d'arguments dans la définition de la fonction. Les paramètres du reste ne sont pas comptés.
345
343
346
-
Si la fonction est déclarée en tant qu'expression de fonction (et non dans le flux du code principal) et qu'elle porte `name`, elle est appelée expression de fonction nommée. Le nom peut être utilisé à l'intérieur pour se référencer, pour des appels récursifs ou autres.
344
+
Si la fonction est déclarée en tant qu'expression de fonction (et non dans le flux du code principal) et qu'elle porte un nom, elle est appelée expression de fonction nommée. Le nom peut être utilisé à l'intérieur pour se référencer, pour des appels récursifs ou autres.
347
345
346
+
Les fonctions peuvent également comporter des propriétés supplémentaires. De nombreuses bibliothèques JavaScript bien connues font un grand usage de cette fonctionnalité.
348
347
349
-
Ils créent une fonction "principale" et y attachent de nombreuses autres fonctions "d'assistance". Par exemple, la bibliothèque [jquery](https://jquery.com) crée une fonction nommée `$`. La bibliothèque [lodash](https://lodash.com) crée une fonction `_`. Et ajoute ensuite `_.clone`,`_.keyBy` et d'autres propriétés (voir la [doc](https://lodash.com/docs) lorsque vous souhaitez en savoir plus à leur sujet). En fait, elles le font pour réduire leur pollution de l'espace global, de sorte qu'une seule bibliothèque ne donne qu'une seule variable globale. Cela réduit la possibilité de conflits de noms.
348
+
Elles créent une fonction "principale" et y attachent de nombreuses autres fonctions "d'assistance". Par exemple, la bibliothèque [jQuery](https://jquery.com) crée une fonction nommée `$`. La bibliothèque [lodash](https://lodash.com) crée une fonction `_` et ajoute ensuite `_.clone`,`_.keyBy` et d'autres propriétés (voir la [doc](https://lodash.com/docs) lorsque vous souhaitez en savoir plus à leur sujet). En fait, elles le font pour réduire leur pollution de l'espace global, de sorte qu'une seule bibliothèque ne donne qu'une seule variable globale. Cela réduit la possibilité de conflits de noms.
350
349
351
350
Ainsi, une fonction peut faire un travail utile par elle-même et aussi porter un tas d’autres fonctionnalités dans les propriétés.
0 commit comments