diff options
author | julieng <julien.gattelier@gmail.com> | 2021-08-03 08:03:23 +0200 |
---|---|---|
committer | SphinxKnight <SphinxKnight@users.noreply.github.com> | 2021-09-03 08:08:25 +0200 |
commit | bf8e099b9c8b3c60d60b3712b4fc97b052c39887 (patch) | |
tree | c101746d082c9581c94f5937519c7d0e2f4af8cb /files/fr/web/javascript/guide/functions | |
parent | 844f5103992238c0c23203286dad16a466e89c97 (diff) | |
download | translated-content-bf8e099b9c8b3c60d60b3712b4fc97b052c39887.tar.gz translated-content-bf8e099b9c8b3c60d60b3712b4fc97b052c39887.tar.bz2 translated-content-bf8e099b9c8b3c60d60b3712b4fc97b052c39887.zip |
convert content to md
Diffstat (limited to 'files/fr/web/javascript/guide/functions')
-rw-r--r-- | files/fr/web/javascript/guide/functions/index.md | 572 |
1 files changed, 296 insertions, 276 deletions
diff --git a/files/fr/web/javascript/guide/functions/index.md b/files/fr/web/javascript/guide/functions/index.md index 972c9f6286..3c909fba2c 100644 --- a/files/fr/web/javascript/guide/functions/index.md +++ b/files/fr/web/javascript/guide/functions/index.md @@ -9,41 +9,42 @@ tags: translation_of: Web/JavaScript/Guide/Functions original_slug: Web/JavaScript/Guide/Fonctions --- -<p>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Boucles_et_it%C3%A9ration", "Web/JavaScript/Guide/Expressions_et_Op%C3%A9rateurs")}}</p> +{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Boucles_et_it%C3%A9ration", "Web/JavaScript/Guide/Expressions_et_Op%C3%A9rateurs")}} -<p>Les fonctions font partie des briques fondamentales de JavaScript. Une fonction est une procédure JavaScript, un ensemble d'instructions effectuant une tâche ou calculant une valeur. Afin d'utiliser une fonction, il est nécessaire de l'avoir auparavant définie au sein de la portée dans laquelle on souhaite l'appeler.</p> +Les fonctions font partie des briques fondamentales de JavaScript. Une fonction est une procédure JavaScript, un ensemble d'instructions effectuant une tâche ou calculant une valeur. Afin d'utiliser une fonction, il est nécessaire de l'avoir auparavant définie au sein de la portée dans laquelle on souhaite l'appeler. -<p>On pourra également lire <a href="/fr/docs/Web/JavaScript/Reference/Fonctions">le chapitre de la référence JavaScript sur les fonctions</a> pour étudier plus en détails ce concept</p> +On pourra également lire [le chapitre de la référence JavaScript sur les fonctions](/fr/docs/Web/JavaScript/Reference/Fonctions) pour étudier plus en détails ce concept -<h2 id="Définir_des_fonctions">Définir des fonctions</h2> +## Définir des fonctions -<h3 id="Les_déclarations_de_fonctions">Les déclarations de fonctions</h3> +### Les déclarations de fonctions -<p>Une <strong>définition de fonction</strong> (aussi appelée <strong>déclaration de fonction</strong> ou <strong>instruction de fonction</strong>) est construite avec le mot-clé <a href="/fr/docs/Web/JavaScript/Reference/Instructions/function"><code>function</code></a>, suivi par :</p> +Une **définition de fonction** (aussi appelée **déclaration de fonction** ou **instruction de fonction**) est construite avec le mot-clé [`function`](/fr/docs/Web/JavaScript/Reference/Instructions/function), suivi par : -<ul> - <li>Le nom de la fonction.</li> - <li>Une liste d'arguments à passer à la fonction, entre parenthèses et séparés par des virgules.</li> - <li>Les instructions JavaScript définissant la fonction, entre accolades, <code>{ }</code>.</li> -</ul> +- Le nom de la fonction. +- Une liste d'arguments à passer à la fonction, entre parenthèses et séparés par des virgules. +- Les instructions JavaScript définissant la fonction, entre accolades, `{ }`. -<p>Le code suivant, par exemple, définit une fonction intitulée <code>carré</code> :</p> +Le code suivant, par exemple, définit une fonction intitulée `carré` : -<pre class="brush: js">function carré(nombre) { +```js +function carré(nombre) { return nombre * nombre; } -</pre> +``` -<p>La fonction <code>carré</code> prend un seul argument, appelé <code>nombre</code>. La fonction est composée d'une seule instruction qui renvoie l'argument de la fonction (<code>nombre</code>) multiplié par lui-même. L'instruction <a href="/fr/docs/Web/JavaScript/Reference/Instructions/return"><code>return</code></a> spécifie la valeur qui est renvoyée par la fonction.</p> +La fonction `carré` prend un seul argument, appelé `nombre`. La fonction est composée d'une seule instruction qui renvoie l'argument de la fonction (`nombre`) multiplié par lui-même. L'instruction [`return`](/fr/docs/Web/JavaScript/Reference/Instructions/return) spécifie la valeur qui est renvoyée par la fonction. -<pre class="brush: js">return nombre * nombre; -</pre> +```js +return nombre * nombre; +``` -<p>Les paramètres primitifs (comme les nombres) sont passés à la fonction <strong>par valeur</strong>. La valeur est passée à la fonction mais si cette dernière change la valeur du paramètre, cela n'aura pas d'impact au niveau global ou au niveau de ce qui a appelé la fonction.</p> +Les paramètres primitifs (comme les nombres) sont passés à la fonction **par valeur**. La valeur est passée à la fonction mais si cette dernière change la valeur du paramètre, cela n'aura pas d'impact au niveau global ou au niveau de ce qui a appelé la fonction. -<p>Si l'argument passé à la fonction est un objet (une valeur non-primitive, comme un objet {{jsxref("Array")}} ou un objet défini par l'utilisateur), et que la fonction change les propriétés de cet objet, ces changements seront visibles en dehors de la fonction. Par exemple :</p> +Si l'argument passé à la fonction est un objet (une valeur non-primitive, comme un objet {{jsxref("Array")}} ou un objet défini par l'utilisateur), et que la fonction change les propriétés de cet objet, ces changements seront visibles en dehors de la fonction. Par exemple : -<pre class="brush: js">function maFonction(monObjet) { +```js +function maFonction(monObjet) { monObjet.fabricant = "Toyota"; } @@ -55,13 +56,12 @@ x = mavoiture.fabricant; // x aura la valeur "Honda" maFonction(mavoiture); y = mavoiture.fabricant; // y aura la valeur "Toyota" // (la propriété fabricant a été modifiée par la fonction) -</pre> +``` -<div class="note"> -<p><strong>Note :</strong> Affecter un nouvel objet au paramètre n'aura <strong>pas</strong> d'effet en dehors de la fonction car cela revient à changer la valeur du paramètre plutôt que la valeur d'une des propriétés de l'objet. Par exemple :</p> -</div> +> **Note :** Affecter un nouvel objet au paramètre n'aura **pas** d'effet en dehors de la fonction car cela revient à changer la valeur du paramètre plutôt que la valeur d'une des propriétés de l'objet. Par exemple : -<pre class="brush: js">function maFonction(monObjet) { +```js +function maFonction(monObjet) { monObjet = {fabricant: "Ford", modèle: "Focus", année: 2006}; } @@ -72,78 +72,86 @@ x = mavoiture.fabricant; // x reçoit la valeur "Honda" maFonction(mavoiture); y = mavoiture.fabricant; // y reçoit la valeur "Honda" -</pre> +``` -<p>Dans le premier exemple, l'objet <code>mavoiture </code>était passé à la fonction <code>maFonction</code> qui le modifiait. Dans le second exemple, la fonction n'a pas modifié l'objet qui avait été passé en argument, elle a créé une nouvelle variable locale, possédant le même nom que l'objet global passé en argument : il n'y a donc pas de modifications sur cet objet global.</p> +Dans le premier exemple, l'objet `mavoiture `était passé à la fonction `maFonction` qui le modifiait. Dans le second exemple, la fonction n'a pas modifié l'objet qui avait été passé en argument, elle a créé une nouvelle variable locale, possédant le même nom que l'objet global passé en argument : il n'y a donc pas de modifications sur cet objet global. -<h3 id="Les_expressions_de_fonction">Les expressions de fonction</h3> +### Les expressions de fonction -<p>Syntaxiquement, la déclaration de fonction utilisée ci-dessus est une instruction. On peut également créer une fonction grâce à une <strong><a href="/fr/docs/Web/JavaScript/Reference/Opérateurs/L_opérateur_function">expression de fonction</a></strong>. De telles fonctions peuvent être <strong>anonymes</strong> (ne pas avoir de nom correspondant). La fonction <code>carré </code>aurait pu être définie de la façon suivante :</p> +Syntaxiquement, la déclaration de fonction utilisée ci-dessus est une instruction. On peut également créer une fonction grâce à une **[expression de fonction](/fr/docs/Web/JavaScript/Reference/Opérateurs/L_opérateur_function)**. De telles fonctions peuvent être **anonymes** (ne pas avoir de nom correspondant). La fonction `carré `aurait pu être définie de la façon suivante : -<pre class="brush: js">var carré = function (nombre) { return nombre * nombre }; -var x = carré(4); //x reçoit la valeur 16</pre> +```js +var carré = function (nombre) { return nombre * nombre }; +var x = carré(4); //x reçoit la valeur 16 +``` -<p>Cependant, un nom peut être utilisé dans une expression de fonction, ce afin de l'utiliser dans la fonction (récursivité) ou afin de l'identifier dans les appels tracés par un éventuel débogueur :</p> +Cependant, un nom peut être utilisé dans une expression de fonction, ce afin de l'utiliser dans la fonction (récursivité) ou afin de l'identifier dans les appels tracés par un éventuel débogueur : -<pre class="brush: js">var factorielle = function fac(n) { return n < 2 ? 1 : n * fac(n - 1) }; +```js +var factorielle = function fac(n) { return n < 2 ? 1 : n * fac(n - 1) }; console.log(factorielle(3)); -</pre> +``` -<p>Les expressions de fonction sont pratiques lorsqu'il s'agit de passer une fonction comme argument d'une autre fonction. Dans l'exemple qui suit, la fonction <code>map</code> est définie et appelée avec une fonction anonyme comme premier argument :</p> +Les expressions de fonction sont pratiques lorsqu'il s'agit de passer une fonction comme argument d'une autre fonction. Dans l'exemple qui suit, la fonction `map` est définie et appelée avec une fonction anonyme comme premier argument : -<pre class="brush: js">function map(f, a) { +```js +function map(f, a) { var resultat = []; // Créer un nouveau tableau Array for (var i = 0; i != a.length; i++) resultat[i] = f(a[i]); return resultat; } -</pre> +``` -<p>Le code suivant applique la fonction <code>cube</code> sur chacun des éléments du tableau :</p> +Le code suivant applique la fonction `cube` sur chacun des éléments du tableau : -<pre class="brush: js">var cube = function(x) { return x * x * x}; // Une expression de fonction +```js +var cube = function(x) { return x * x * x}; // Une expression de fonction map(cube, [0, 1, 2, 5, 10]); -</pre> +``` -<p>Le résultat de la dernière instruction est le tableau [0, 1, 8, 125, 1000].</p> +Le résultat de la dernière instruction est le tableau \[0, 1, 8, 125, 1000]. -<p>En JavaScript, une fonction peut être définie selon une condition. Le fragment de code qui suit définit une fonction seulement si <code>num</code> vaut 0 :</p> +En JavaScript, une fonction peut être définie selon une condition. Le fragment de code qui suit définit une fonction seulement si `num` vaut 0 : -<pre class="brush: js">var maFonction; +```js +var maFonction; if (num === 0){ maFonction = function(monObjet) { monObjet.fabricant = "Toyota" } -}</pre> +} +``` -<p>Une autre façon de définir des fonctions est d'utiliser le constructeur de l'objet {{jsxref("Function")}} afin de créer des fonctions à partir d'une chaîne lors de l'exécution, de la même façon que {{jsxref("Objets_globaux/eval", "eval()")}}.</p> +Une autre façon de définir des fonctions est d'utiliser le constructeur de l'objet {{jsxref("Function")}} afin de créer des fonctions à partir d'une chaîne lors de l'exécution, de la même façon que {{jsxref("Objets_globaux/eval", "eval()")}}. -<p>Une <strong>méthode</strong> est une fonction étant une propriété d'un objet. Vous trouverez plus de détails sur ces éléments dans le chapitre suivant du guide : <a href="/fr/docs/JavaScript/Guide/Utiliser_les_objets">Utiliser les objets</a>.</p> +Une **méthode** est une fonction étant une propriété d'un objet. Vous trouverez plus de détails sur ces éléments dans le chapitre suivant du guide : [Utiliser les objets](/fr/docs/JavaScript/Guide/Utiliser_les_objets). -<h2 id="Appeler_des_fonctions">Appeler des fonctions</h2> +## Appeler des fonctions -<p>La seule définition d'une fonction ne permet pas d'exécuter la fonction. Cela permet de lui donner un nom et de définir ce qui doit être fait lorsque la fonction est appelée. <strong>Appeler</strong> la fonction permet d'effectuer les actions des instructions avec les paramètres indiqués. Par exemple, si on définit la fonction <code>carré</code>, on peut l'appeler de la façon suivante :</p> +La seule définition d'une fonction ne permet pas d'exécuter la fonction. Cela permet de lui donner un nom et de définir ce qui doit être fait lorsque la fonction est appelée. **Appeler** la fonction permet d'effectuer les actions des instructions avec les paramètres indiqués. Par exemple, si on définit la fonction `carré`, on peut l'appeler de la façon suivante : -<pre class="brush: js">carré(5); -</pre> +```js +carré(5); +``` -<p>Cette instruction appellera la fonction avec un argument valant 5. La fonction exécute ses instructions et renvoie la valeur 25.</p> +Cette instruction appellera la fonction avec un argument valant 5. La fonction exécute ses instructions et renvoie la valeur 25. -<p>Les fonctions doivent appartenir à la portée dans laquelle elles sont appelées. En revanche, la déclaration d'une fonction peut être faite après l'appel :</p> +Les fonctions doivent appartenir à la portée dans laquelle elles sont appelées. En revanche, la déclaration d'une fonction peut être faite après l'appel : -<pre class="brush: js">console.log(carré(5)); +```js +console.log(carré(5)); /* ... */ function carré(n) { return n*n } -</pre> +``` -<p>La portée d'une fonction est la fonction dans laquelle elle est déclarée ou le programme entier si elle est déclarée au niveau le plus haut.</p> +La portée d'une fonction est la fonction dans laquelle elle est déclarée ou le programme entier si elle est déclarée au niveau le plus haut. -<div class="note"> -<p><strong>Note :</strong> Cela ne fonctionne que si la définition de la fonction utilise la syntaxe précédente (<code>function nomFonction(){}</code>). Le code ci-dessous ne fonctionnera pas :</p> -</div> +> **Note :** Cela ne fonctionne que si la définition de la fonction utilise la syntaxe précédente (`function nomFonction(){}`). Le code ci-dessous ne fonctionnera pas : -<pre class="example-bad brush: js">console.log(carré); // La fonction carré est remontée/hoisted mais vaut undefined +```js example-bad +console.log(carré); // La fonction carré est remontée/hoisted mais vaut undefined console.log(carré(5)); // TypeError: carré is not a function var carré = function (n) { return n * n; @@ -157,37 +165,40 @@ console.log(carré2(5)); // TypeError: carré2 is not a function let carré2 = function (n) { return n * n; } -</pre> +``` -<p>Les arguments d'une fonction ne sont pas limités aux chaînes de caractères et aux nombres. Il est possible de passer des objets. La fonction <code>show_props</code> (définie dans le chapitre sur <a href="/fr/docs/JavaScript/Guide/Utiliser_les_objets">l'utilisation des objets</a>) est un exemple de fonction utilisant un argument qui est un objet.</p> +Les arguments d'une fonction ne sont pas limités aux chaînes de caractères et aux nombres. Il est possible de passer des objets. La fonction `show_props` (définie dans le chapitre sur [l'utilisation des objets](/fr/docs/JavaScript/Guide/Utiliser_les_objets)) est un exemple de fonction utilisant un argument qui est un objet. -<p>Une fonction peut être récursive, c'est-à-dire qu'elle peut s'appeler elle-même. Voici la fonction qui calcule récursivement la factorielle d'un nombre :</p> +Une fonction peut être récursive, c'est-à-dire qu'elle peut s'appeler elle-même. Voici la fonction qui calcule récursivement la factorielle d'un nombre : -<pre class="brush: js">function factorielle(n){ +```js +function factorielle(n){ if ((n === 0) || (n === 1)) return 1; else return (n * factorielle(n - 1)); } -</pre> +``` -<p>On peut ensuite calculer les factorielles des nombres 1 à 5 :</p> +On peut ensuite calculer les factorielles des nombres 1 à 5 : -<pre class="brush: js">var a, b, c, d, e; +```js +var a, b, c, d, e; a = factorielle(1); // a reçoit la valeur 1 b = factorielle(2); // b reçoit la valeur 2 c = factorielle(3); // c reçoit la valeur 6 d = factorielle(4); // d reçoit la valeur 24 e = factorielle(5); // e reçoit la valeur 120 -</pre> +``` -<p>Il existe d'autres façons d'appeler des fonctions. Il existe souvent des cas où une fonction doit être appelée dynamiquement, où le nombre d'arguments peut varier, où le contexte de l'appel d'une fonction doit être créé en fonction d'un objet déterminé lors de l'exécution. Les fonctions sont des objets, en tant que tels, elles possèdent des méthodes (voir la page sur l'objet {{jsxref("Function")}}). L'une d'entre elles, {{jsxref("Function.apply","apply()")}} peut être utilisée pour réaliser le dernier cas de figure (exécution d'une fonction avec un objet déterminé à l'exécution).</p> +Il existe d'autres façons d'appeler des fonctions. Il existe souvent des cas où une fonction doit être appelée dynamiquement, où le nombre d'arguments peut varier, où le contexte de l'appel d'une fonction doit être créé en fonction d'un objet déterminé lors de l'exécution. Les fonctions sont des objets, en tant que tels, elles possèdent des méthodes (voir la page sur l'objet {{jsxref("Function")}}). L'une d'entre elles, {{jsxref("Function.apply","apply()")}} peut être utilisée pour réaliser le dernier cas de figure (exécution d'une fonction avec un objet déterminé à l'exécution). -<h2 id="Portée_d'une_fonction">Portée d'une fonction</h2> +## Portée d'une fonction -<p>On ne peut pas accéder aux variables définies dans une fonction en dehors de cette fonction : ces variables n'existent que dans la portée de la fonction. En revanche, une fonction peut accéder aux différentes variables et fonctions qui appartiennent à la portée dans laquelle elle est définie. Une fonction définie dans une autre fonction peut également accéder à toutes les variables de la fonction « parente » et à toute autre variable accessible depuis la fonction « parente ».</p> +On ne peut pas accéder aux variables définies dans une fonction en dehors de cette fonction : ces variables n'existent que dans la portée de la fonction. En revanche, une fonction peut accéder aux différentes variables et fonctions qui appartiennent à la portée dans laquelle elle est définie. Une fonction définie dans une autre fonction peut également accéder à toutes les variables de la fonction « parente » et à toute autre variable accessible depuis la fonction « parente ». -<pre class="brush: js">// Les variables suivantes sont globales +```js +// Les variables suivantes sont globales var num1 = 20, num2 = 3, nom = "Licorne"; @@ -212,112 +223,117 @@ function getScore () { } getScore(); // Renvoie "Licorne a marqué 5" -</pre> +``` -<h2 id="Portée_et_pile_de_fonctions">Portée et pile de fonctions</h2> +## Portée et pile de fonctions -<h3 id="La_récursivité">La récursivité</h3> +### La récursivité -<p>Une fonction peut faire référence à elle-même et s'appeler elle-même. Il existe trois moyens pour qu'une fonction fasse référence à elle-même :</p> +Une fonction peut faire référence à elle-même et s'appeler elle-même. Il existe trois moyens pour qu'une fonction fasse référence à elle-même : -<ol> - <li>Le nom de la fonction</li> - <li><code><a href="/fr/docs/Web/JavaScript/Reference/Fonctions/arguments/callee">arguments.callee</a></code></li> - <li>Une variable de la portée qui fait référence à la fonction</li> -</ol> +1. Le nom de la fonction +2. [`arguments.callee`](/fr/docs/Web/JavaScript/Reference/Fonctions/arguments/callee) +3. Une variable de la portée qui fait référence à la fonction -<p>Par exemple, avec la définition de fonction suivante :</p> +Par exemple, avec la définition de fonction suivante : -<pre class="brush: js">var toto = function truc() { +```js +var toto = function truc() { // les instructions de la fonction -};</pre> +}; +``` -<p>Dans le corps de la fonction, ces trois éléments seront équivalents :</p> +Dans le corps de la fonction, ces trois éléments seront équivalents : -<ol> - <li><code>truc()</code></li> - <li><code>arguments.callee()</code></li> - <li><code>toto()</code></li> -</ol> +1. `truc()` +2. `arguments.callee()` +3. `toto()` -<p>Une fonction qui s'appelle elle-même est appelée une fonction <em>récursive</em>. Sous certains aspects, une récursion est semblable à une boucle : toutes les deux exécutent le même code plusieurs fois et toutes les deux requièrent une condition d'arrêt (pour éviter une boucle ou une récursion infinie). Par exemple, ce fragment de code utilisant une boucle :</p> +Une fonction qui s'appelle elle-même est appelée une fonction _récursive_. Sous certains aspects, une récursion est semblable à une boucle : toutes les deux exécutent le même code plusieurs fois et toutes les deux requièrent une condition d'arrêt (pour éviter une boucle ou une récursion infinie). Par exemple, ce fragment de code utilisant une boucle : -<pre class="brush: js">var x = 0; -while (x < 10) { // "x < 10" représente la condition d'arrêt +```js +var x = 0; +while (x < 10) { // "x < 10" représente la condition d'arrêt // faire quelque chose x++; -}</pre> +} +``` -<p>pourra être converti en une fonction récursive de la façon suivante :</p> +pourra être converti en une fonction récursive de la façon suivante : -<pre class="brush: js">function boucle(x) { - if (x >= 10) // "x >= 10" représente la condition d'arrêt (équivalent à "!(x < 10)") +```js +function boucle(x) { + if (x >= 10) // "x >= 10" représente la condition d'arrêt (équivalent à "!(x < 10)") return; // faire quelque chose boucle(x + 1); // l'appel récursif } -boucle(0);</pre> +boucle(0); +``` -<p>Malgré cela, certains algorithmes ne peuvent pas être convertis en boucles itératives. Ainsi, récupérer l'ensemble des nœuds d'un arbre (le <a href="/fr/docs/Web/API/Référence_du_DOM_Gecko">DOM</a> par exemple) se fait plus simplement en utilisant la récursivité :</p> +Malgré cela, certains algorithmes ne peuvent pas être convertis en boucles itératives. Ainsi, récupérer l'ensemble des nœuds d'un arbre (le [DOM](/fr/docs/Web/API/Référence_du_DOM_Gecko) par exemple) se fait plus simplement en utilisant la récursivité : -<pre class="brush: js">function parcourirArbre(noeud) { +```js +function parcourirArbre(noeud) { if (noeud === null) // return; // faire quelque chose avec le noeud - for (var i = 0; i < noeud.childNodes.length; i++) { + for (var i = 0; i < noeud.childNodes.length; i++) { parcourirArbre(noeud.childNodes[i]); } -}</pre> +} +``` -<p>Contrairement à l'exemple précédent avec la fonction <code>boucle</code>, ici, chaque appel récursif entraîne lui-même plusieurs appels (et non un seul).</p> +Contrairement à l'exemple précédent avec la fonction `boucle`, ici, chaque appel récursif entraîne lui-même plusieurs appels (et non un seul). -<p>Théoriquement, il est possible de convertir tout algorithme récursif en un algorithme non récursif (avec des boucles par exemple). Généralement, la logique obtenue est plus complexe et nécessite l'utilisation d'une <a href="https://fr.wikipedia.org/wiki/Pile_%28informatique%29">pile</a>. La récursivité utilise également une pile, la pile de fonction.</p> +Théoriquement, il est possible de convertir tout algorithme récursif en un algorithme non récursif (avec des boucles par exemple). Généralement, la logique obtenue est plus complexe et nécessite l'utilisation d'une [pile](https://fr.wikipedia.org/wiki/Pile_%28informatique%29). La récursivité utilise également une pile, la pile de fonction. -<p>Ce type de « comportement » peut-être observé avec l'exemple suivant :</p> +Ce type de « comportement » peut-être observé avec l'exemple suivant : -<pre class="brush: js">function toto(i) { - if (i < 0) +```js +function toto(i) { + if (i < 0) return; console.log('début : ' + i); toto(i - 1); console.log('fin : ' + i); } -toto(3);</pre> +toto(3); +``` -<p>qui affichera :</p> +qui affichera : -<pre class="brush: js">début : 3 +```js +début : 3 début : 2 début : 1 début : 0 fin : 0 fin : 1 fin : 2 -fin : 3</pre> +fin : 3 +``` -<h3 id="Fonctions_imbriquées_et_fermetures">Fonctions imbriquées et fermetures</h3> +### Fonctions imbriquées et fermetures -<p>Il est possible d'imbriquer une fonction dans une autre fonction. La portée de la fonction fille (celle qui est imbriquée) n'est pas contenue dans la portée de la fonction parente. En revanche, la fonction fille bénéficie bien des informations de la fonction parente grâce à sa portée. On a ce qu'on appelle une fermeture (<em>closure</em> en anglais). Une fermeture est une expression (généralement une fonction) qui accède à des variables libres ainsi qu'à un environnement qui lie ces variables (ce qui « ferme » l'expression).</p> +Il est possible d'imbriquer une fonction dans une autre fonction. La portée de la fonction fille (celle qui est imbriquée) n'est pas contenue dans la portée de la fonction parente. En revanche, la fonction fille bénéficie bien des informations de la fonction parente grâce à sa portée. On a ce qu'on appelle une fermeture (_closure_ en anglais). Une fermeture est une expression (généralement une fonction) qui accède à des variables libres ainsi qu'à un environnement qui lie ces variables (ce qui « ferme » l'expression). -<p>Une fonction imbriquée étant une fermeture, cela signifie qu'une fonction imbriquée peut en quelque sorte hériter des arguments et des variables de la fonction parente.</p> +Une fonction imbriquée étant une fermeture, cela signifie qu'une fonction imbriquée peut en quelque sorte hériter des arguments et des variables de la fonction parente. -<p>En résumé :</p> +En résumé : -<ul> - <li>La fonction imbriquée ne peut être utilisée qu'à partir des instructions de la fonction parente.</li> -</ul> +- La fonction imbriquée ne peut être utilisée qu'à partir des instructions de la fonction parente. -<ul> - <li>La fonction imbriquée forme une fermeture : elle peut utiliser les arguments et les variables de la fonction parente. En revanche, la fonction parente ne peut pas utiliser les arguments et les variables de la fonction fille.</li> -</ul> +<!----> -<div class="note"> -<p><strong>Note :</strong> Sur les fermetures, voir également <a href="/fr/docs/Web/JavaScript/Closures">l'article à ce sujet</a>.</p> -</div> +- La fonction imbriquée forme une fermeture : elle peut utiliser les arguments et les variables de la fonction parente. En revanche, la fonction parente ne peut pas utiliser les arguments et les variables de la fonction fille. -<p>L'exemple qui suit illustre l'imbrication de fonctions :</p> +> **Note :** Sur les fermetures, voir également [l'article à ce sujet](/fr/docs/Web/JavaScript/Closures). -<pre class="brush: js">function ajouteCarrés(a, b) { +L'exemple qui suit illustre l'imbrication de fonctions : + +```js +function ajouteCarrés(a, b) { function carré(x) { return x * x; } @@ -325,11 +341,13 @@ fin : 3</pre> } a = ajouteCarrés(2,3); // renvoie 13 b = ajouteCarrés(3,4); // renvoie 25 -c = ajouteCarrés(4,5); // renvoie 41</pre> +c = ajouteCarrés(4,5); // renvoie 41 +``` -<p>La fonction interne étant une fermeture, on peut appeler la fonction parente afin de définir les arguments pour la fonction englobante et ceux de la fonction fille :</p> +La fonction interne étant une fermeture, on peut appeler la fonction parente afin de définir les arguments pour la fonction englobante et ceux de la fonction fille : -<pre class="brush: js">function parente(x) { +```js +function parente(x) { function fille(y) { return x + y; } @@ -338,21 +356,23 @@ c = ajouteCarrés(4,5); // renvoie 41</pre> fn_fille = parente(3); // Fournit une fonction qui ajoute 3 à ce qu'on lui donnera résultat = fn_fille(5); // renvoie 8 -résultat1 = parente(3)(5); // renvoie 8</pre> +résultat1 = parente(3)(5); // renvoie 8 +``` -<h3 id="Préservation_des_variables">Préservation des variables</h3> +### Préservation des variables -<p>Dans l'exemple précédent, <code>x</code> a été « préservé » lorsque la fonction <code>fille</code> a été renvoyée. Une fermeture conserve les arguments et les variables de chaque portée qu'elle référence. Chaque appel à la fonction parente pouvant fournir un contexte différents selon les arguments, cela entraînera la création d'une nouvelle fermeture. La mémoire associée ne pourra être libérée que lorsque la fonction <code>fille</code> ne sera plus accessible.</p> +Dans l'exemple précédent, `x` a été « préservé » lorsque la fonction `fille` a été renvoyée. Une fermeture conserve les arguments et les variables de chaque portée qu'elle référence. Chaque appel à la fonction parente pouvant fournir un contexte différents selon les arguments, cela entraînera la création d'une nouvelle fermeture. La mémoire associée ne pourra être libérée que lorsque la fonction `fille` ne sera plus accessible. -<p>Ce mode de fonctionnement n'est pas différent de celui des références vers les objets. Cependant, il est souvent plus compliqué à détecter car les références ne sont pas définies explicitement dans le code et car il n'est pas possible de les inspecter.</p> +Ce mode de fonctionnement n'est pas différent de celui des références vers les objets. Cependant, il est souvent plus compliqué à détecter car les références ne sont pas définies explicitement dans le code et car il n'est pas possible de les inspecter. -<h3 id="Imbriquer_plusieurs_fonctions">Imbriquer plusieurs fonctions</h3> +### Imbriquer plusieurs fonctions -<p>Il est possible d'imbriquer des fonctions sur plus de deux niveaux, par exemple, on peut avoir une fonction A qui contient une fonction B qui contient une fonction C. Les fonctions B et C sont des fermetures et B peut accéder à la portée de A, C peut accéder à la portée de B. Ainsi, C accède à la portée de B qui lui accède à la portée de A, C accède donc à la portée de A (transitivité). Les fermetures peuvent donc contenir plusieurs portées, c'est ce qu'on appelle le <em>chaînage</em> de portées.</p> +Il est possible d'imbriquer des fonctions sur plus de deux niveaux, par exemple, on peut avoir une fonction A qui contient une fonction B qui contient une fonction C. Les fonctions B et C sont des fermetures et B peut accéder à la portée de A, C peut accéder à la portée de B. Ainsi, C accède à la portée de B qui lui accède à la portée de A, C accède donc à la portée de A (transitivité). Les fermetures peuvent donc contenir plusieurs portées, c'est ce qu'on appelle le _chaînage_ de portées. -<p>Par exemple :</p> +Par exemple : -<pre class="brush: js">function A(x) { +```js +function A(x) { function B(y) { function C(z) { console.log(x + y + z); @@ -361,38 +381,40 @@ résultat1 = parente(3)(5); // renvoie 8</pre> } B(2); } -A(1); // affichera 6 (1 + 2 + 3)</pre> +A(1); // affichera 6 (1 + 2 + 3) +``` -<p>Dans cet exemple <code>C</code> accède au <code>y</code> de <code>B</code> et au <code>x</code> de <code>A</code>. Ceci est rendu possible car :</p> +Dans cet exemple `C` accède au `y` de `B` et au `x` de `A`. Ceci est rendu possible car : -<ol> - <li><code>B</code> est une fermeture qui contient <code>A</code>, autrement dit <code>B</code> peut accéder aux arguments et aux variables de <code>A</code>.</li> - <li><code>C</code> est une fermeture qui contient <code>B</code>.</li> - <li>La fermeture de <code>B</code> contient <code>A</code> donc la fermeture de <code>C</code> contient <code>A</code>, <code>C</code> peut ainsi accéder aux arguments et aux variables de <code>B</code> <em>et</em> <code>A</code>. On dit que <code>C</code> <em>chaîne</em> les portées de <code>B</code> et de <code>A</code> (dans cet ordre).</li> -</ol> +1. `B` est une fermeture qui contient `A`, autrement dit `B` peut accéder aux arguments et aux variables de `A`. +2. `C` est une fermeture qui contient `B`. +3. La fermeture de `B` contient `A` donc la fermeture de `C` contient `A`, `C` peut ainsi accéder aux arguments et aux variables de `B` _et_ `A`. On dit que `C` _chaîne_ les portées de `B` et de `A` (dans cet ordre). -<p>La réciproque n'est pas vraie. <code>A</code> ne peut pas accéder à <code>C</code>, car <code>A</code> ne peut pas accéder aux arguments ou aux variables de <code>B</code>, or <code>C</code> est une variable de <code>B</code>. De cette façon, <code>C</code> reste privée en dehors de <code>B</code>.</p> +La réciproque n'est pas vraie. `A` ne peut pas accéder à `C`, car `A` ne peut pas accéder aux arguments ou aux variables de `B`, or `C` est une variable de `B`. De cette façon, `C` reste privée en dehors de `B`. -<h3 id="Conflits_de_nommage">Conflits de nommage</h3> +### Conflits de nommage -<p>Lorsque deux arguments ou variables des portées d'une fermeture ont le même nom, il y a un conflit de noms. Dans ces cas, ce sera la portée la plus imbriquée qui prendra la priorité sur le nom, la portée la plus « externe » aura la priorité la plus faible pour les noms de variables. Du point de vue de la chaîne des portées, la première portée sur la chaîne est la portée la plus imbriquée et la dernière est la portée située le plus à l'extérieur :</p> +Lorsque deux arguments ou variables des portées d'une fermeture ont le même nom, il y a un conflit de noms. Dans ces cas, ce sera la portée la plus imbriquée qui prendra la priorité sur le nom, la portée la plus « externe » aura la priorité la plus faible pour les noms de variables. Du point de vue de la chaîne des portées, la première portée sur la chaîne est la portée la plus imbriquée et la dernière est la portée située le plus à l'extérieur : -<pre class="brush: js">function externe() { +```js +function externe() { var x = 10; function interne(x) { return x; } return interne; } -résultat = externe()(20); // renvoie 20 et pas 10</pre> +résultat = externe()(20); // renvoie 20 et pas 10 +``` -<p>Le conflit se produit à l'instruction <code>return x</code> entre le paramètre x de la fonction <code>interne</code> et la variable <code>x</code> de la fonction <code>externe</code>. La chaîne de portée est ici {<code>interne</code>, <code>externe</code>, objet global}. Ainsi, le paramètre <code>x</code> de <code>interne</code> a la priorité sur la variable <code>x</code> de la fonction <code>externe</code>, le résultat obtenu est donc 20 et non 10.</p> +Le conflit se produit à l'instruction `return x` entre le paramètre x de la fonction `interne` et la variable `x` de la fonction `externe`. La chaîne de portée est ici {`interne`, `externe`, objet global}. Ainsi, le paramètre `x` de `interne` a la priorité sur la variable `x` de la fonction `externe`, le résultat obtenu est donc 20 et non 10. -<h2 id="Fermetures_(closures)">Fermetures (<em>closures</em>)</h2> +## Fermetures (_closures_) -<p>Les fermetures sont l'une des fonctionnalités les plus intéressantes de JavaScript. Comme on l'a vu précédemment, JavaScript permet d'imbriquer des fonctions et la fonction interne aura accès aux variables et paramètres de la fonction parente. À l'inverse, la fonction parente ne pourra pas accéder aux variables liées à la fonction interne. Cela fournit une certaine sécurité pour les variables de la fonction interne. De plus, si la fonction interne peut exister plus longtemps que la fonction parente, les variables et fonctions de la fonction parente pourront exister au travers de la fonction interne. On crée une fermeture lorsque la fonction interne est disponible en dehors de la fonction parente.</p> +Les fermetures sont l'une des fonctionnalités les plus intéressantes de JavaScript. Comme on l'a vu précédemment, JavaScript permet d'imbriquer des fonctions et la fonction interne aura accès aux variables et paramètres de la fonction parente. À l'inverse, la fonction parente ne pourra pas accéder aux variables liées à la fonction interne. Cela fournit une certaine sécurité pour les variables de la fonction interne. De plus, si la fonction interne peut exister plus longtemps que la fonction parente, les variables et fonctions de la fonction parente pourront exister au travers de la fonction interne. On crée une fermeture lorsque la fonction interne est disponible en dehors de la fonction parente. -<pre class="brush: js">var animal = function(nom) { // La fonction externe utilise un paramètre "nom" +```js +var animal = function(nom) { // La fonction externe utilise un paramètre "nom" var getNom = function () { return nom; // La fonction interne accède à la variable "nom" de la fonction externe } @@ -401,11 +423,13 @@ résultat = externe()(20); // renvoie 20 et pas 10</pre> monAnimal = animal("Licorne"); -monAnimal(); // Renvoie "Licorne"</pre> +monAnimal(); // Renvoie "Licorne" +``` -<p>Bien entendu, dans la pratique, les cas peuvent être plus complexes. On peut renvoyer un objet qui contient des méthodes manipulant les variables internes de la fonction parente.</p> +Bien entendu, dans la pratique, les cas peuvent être plus complexes. On peut renvoyer un objet qui contient des méthodes manipulant les variables internes de la fonction parente. -<pre class="brush: js">var créerAnimal = function (nom) { +```js +var créerAnimal = function (nom) { var sexe; return { @@ -422,7 +446,7 @@ monAnimal(); // Renvoie "Licorne"</pre> }, setSexe: function(nouveauSexe) { - if (typeof nouveauSexe == "string" && (nouveauSexe.toLowerCase() == "mâle" || nouveauSexe.toLowerCase() == "femelle")) { + if (typeof nouveauSexe == "string" && (nouveauSexe.toLowerCase() == "mâle" || nouveauSexe.toLowerCase() == "femelle")) { sexe = nouveauSexe; } } @@ -435,126 +459,141 @@ animal.getNom(); // Licorne animal.setNom("Bobby"); animal.setSexe("mâle"); animal.getSexe(); // mâle -animal.getNom(); // Bobby</pre> +animal.getNom(); // Bobby +``` -<p>Dans le code précédent, la variable <code>nom</code> est de la fonction externe est accessible depuis les fonctions internes. Il est impossible d'accéder aux variables internes en dehors des fonctions internes. Les variables internes agissent comme des coffres-forts pour les fonctions internes. Elles permettent d'avoir un accès persistent et encapsulé aux données internes. Pour les fonctions, il n'est pas nécessaire de les affecter à une variable ou même de les nommer.</p> +Dans le code précédent, la variable `nom` est de la fonction externe est accessible depuis les fonctions internes. Il est impossible d'accéder aux variables internes en dehors des fonctions internes. Les variables internes agissent comme des coffres-forts pour les fonctions internes. Elles permettent d'avoir un accès persistent et encapsulé aux données internes. Pour les fonctions, il n'est pas nécessaire de les affecter à une variable ou même de les nommer. -<pre class="brush: js">var getCode = (function (){ - var codeAPI = "0]Eal(eh&2"; // Un code qu'on ne souhaite pas diffuser ni modifier +```js +var getCode = (function (){ + var codeAPI = "0]Eal(eh&2"; // Un code qu'on ne souhaite pas diffuser ni modifier return function () { return codeAPI; }; })(); -getCode(); // Renvoie la valeur du code</pre> +getCode(); // Renvoie la valeur du code +``` -<p>Il y a malgré tout quelques pièges auxquels il faut faire attention lorsqu'on utilise les fermetures. Si une fonction imbriquée définit une variable avec le même nom que le nom d'une variable de la portée externe, il n'y aura plus aucun moyen d'accéder à la variable.</p> +Il y a malgré tout quelques pièges auxquels il faut faire attention lorsqu'on utilise les fermetures. Si une fonction imbriquée définit une variable avec le même nom que le nom d'une variable de la portée externe, il n'y aura plus aucun moyen d'accéder à la variable. -<pre class="brush: js">var créerAnimal = function(nom) { // La fonction externe définit une variable appelée "nom" +```js +var créerAnimal = function(nom) { // La fonction externe définit une variable appelée "nom" return { setNom: function(nom) { // La fonction imbriquée définit une variable appelée "nom" nom = nom; // ??? comment accéder à la variable "nom" définie par la fonction externe } } -}</pre> +} +``` -<p>L<code>'opérateur </code><a href="/fr/docs/Web/JavaScript/Reference/Op%C3%A9rateurs/L_op%C3%A9rateur_this"><code>this</code></a> doit être traité avec précaution dans les fermetures. Attention, <code>this</code> fait référence au contexte où la fonction est appelée et non à l'endroit où il est défini.</p> +L`'opérateur `[`this`](/fr/docs/Web/JavaScript/Reference/Op%C3%A9rateurs/L_op%C3%A9rateur_this) doit être traité avec précaution dans les fermetures. Attention, `this` fait référence au contexte où la fonction est appelée et non à l'endroit où il est défini. -<h2 id="Utiliser_l'objet_arguments">Utiliser l'objet <code>arguments</code></h2> +## Utiliser l'objet `arguments` -<p>Les arguments d'une fonction sont maintenus dans un objet semblable à un tableau. Dans une fonction, il est possible d'utiliser les arguments passés à la fonction de la façon suivante :</p> +Les arguments d'une fonction sont maintenus dans un objet semblable à un tableau. Dans une fonction, il est possible d'utiliser les arguments passés à la fonction de la façon suivante : -<pre class="brush: js">arguments[i]</pre> +```js +arguments[i] +``` -<p>où <code>i</code> représente l'index ordinal de l'argument (le premier argument ayant un indice à 0). On accède donc au premier argument avec <code>arguments[0]</code>. Le nombre total d'arguments est fourni grâce à <code>arguments.length</code>.</p> +où `i` représente l'index ordinal de l'argument (le premier argument ayant un indice à 0). On accède donc au premier argument avec `arguments[0]`. Le nombre total d'arguments est fourni grâce à `arguments.length`. -<p>En utilisant l'objet <code>arguments</code>, il est possible de recenser les arguments supplémentaires fournis à la fonction si jamais il y a plus d'arguments fournis que requis. Cet objet est souvent utile si on ne connaît pas le nombre d'arguments passés à la fonction. La propriété <code>arguments.length</code> permet de déterminer le nombre d'arguments réellement passés à la fonction. On peut donc ensuite accéder aux différents arguments en parcourant l'objet <code>arguments</code>.</p> +En utilisant l'objet `arguments`, il est possible de recenser les arguments supplémentaires fournis à la fonction si jamais il y a plus d'arguments fournis que requis. Cet objet est souvent utile si on ne connaît pas le nombre d'arguments passés à la fonction. La propriété `arguments.length` permet de déterminer le nombre d'arguments réellement passés à la fonction. On peut donc ensuite accéder aux différents arguments en parcourant l'objet `arguments`. -<p>Par exemple, on peut construire une fonction qui concatène plusieurs chaînes. Le seul argument formellement défini sera la chaîne utilisée pour concaténer les différentes chaînes. On peut définir la fonction de la façon suivante :</p> +Par exemple, on peut construire une fonction qui concatène plusieurs chaînes. Le seul argument formellement défini sera la chaîne utilisée pour concaténer les différentes chaînes. On peut définir la fonction de la façon suivante : -<pre class="brush: js">function monConcat(séparateur) { +```js +function monConcat(séparateur) { var result = ""; // on initialise la liste var i; // on parcourt les arguments - for (i = 1; i < arguments.length; i++) { + for (i = 1; i < arguments.length; i++) { result += arguments[i] + séparateur; } return result; -}</pre> +} +``` -<p>On peut passer autant d'arguments que nécessaire à cette fonction. Ils seront tous concaténés dans une chaîne finale. Ainsi, on aura :</p> +On peut passer autant d'arguments que nécessaire à cette fonction. Ils seront tous concaténés dans une chaîne finale. Ainsi, on aura : -<pre class="brush: js">// renverra "rouge, orange, bleu, " +```js +// renverra "rouge, orange, bleu, " monConcat(", ", "red", "orange", "blue"); // renverra "éléphant; girafe; lion; singe; " monConcat("; ", "éléphant", "girafe", "lion", "singe"); // renverra "sauge. basilic. origan. poivre. échalotte. " -monConcat(". ", "sauge", "basilic", "origan", "poivre", "échalotte");</pre> +monConcat(". ", "sauge", "basilic", "origan", "poivre", "échalotte"); +``` -<div class="note"> -<p><strong>Note :</strong> <code>arguments</code> est une variable « semblable » à un tableau. Mais ce n'est pas un tableau au sens strict. En effet, il possède un index numéroté ainsi qu'une propriété <code>length</code>. En revanche, il ne possède pas les méthodes classiques de manipulation des tableaux (Array).</p> -</div> +> **Note :** `arguments` est une variable « semblable » à un tableau. Mais ce n'est pas un tableau au sens strict. En effet, il possède un index numéroté ainsi qu'une propriété `length`. En revanche, il ne possède pas les méthodes classiques de manipulation des tableaux (Array). -<p>Voir la page sur l'objet {{jsxref("Function")}} dans la référence JavaScript pour plus d'informations.</p> +Voir la page sur l'objet {{jsxref("Function")}} dans la référence JavaScript pour plus d'informations. -<h2 id="Paramètres_des_fonctions">Paramètres des fonctions</h2> +## Paramètres des fonctions -<p>À partir d'ECMAScript 2015, deux sortes de paramètres sont introduites : les paramètres par défaut et les paramètres du reste.</p> +À partir d'ECMAScript 2015, deux sortes de paramètres sont introduites : les paramètres par défaut et les paramètres du reste. -<h3 id="Les_paramètres_par_défaut">Les paramètres par défaut</h3> +### Les paramètres par défaut -<p>En JavaScript, par défaut, les paramètres des fonctions vaudront <code>undefined</code>. Il peut toutefois être utile de définir une valeur par défaut différente. Les paramètres par défaut permettent de répondre à ce besoin.</p> +En JavaScript, par défaut, les paramètres des fonctions vaudront `undefined`. Il peut toutefois être utile de définir une valeur par défaut différente. Les paramètres par défaut permettent de répondre à ce besoin. -<p>Avant ECMAScript 2015, la stratégie pour manipuler des valeurs par défaut adaptées était de tester si la valeur du paramètre était indéfinie puis de lui affecter la valeur souhaitée si c'était le cas. Par exemple, dans le code qui suit, on ne fournit pas de valeur pour <code>b</code> dans l'appel, la valeur sera <code>undefined</code> lors de l'évaluation de <code>a*b</code> et l'appel à <code>multiplier</code> aurait renvoyé <code>NaN</code>. Pour éviter ça, la deuxième ligne définit une valeur par défaut au cas où <code>b</code> n'est pas renseigné :</p> +Avant ECMAScript 2015, la stratégie pour manipuler des valeurs par défaut adaptées était de tester si la valeur du paramètre était indéfinie puis de lui affecter la valeur souhaitée si c'était le cas. Par exemple, dans le code qui suit, on ne fournit pas de valeur pour `b` dans l'appel, la valeur sera `undefined` lors de l'évaluation de `a*b` et l'appel à `multiplier` aurait renvoyé `NaN`. Pour éviter ça, la deuxième ligne définit une valeur par défaut au cas où `b` n'est pas renseigné : -<pre class="brush: js">function multiplier(a, b) { +```js +function multiplier(a, b) { b = typeof b !== 'undefined' ? b : 1; return a*b; } multiplier(5); // 5 -</pre> +``` -<p>Si on peut utiliser les paramètres par défaut, il n'est plus nécessaire de faire l'opération à l'intérieur du corps de la fonction, il suffit de déclarer que la valeur par défaut pour <code>b</code> est 1 dans la signature de la fonction :</p> +Si on peut utiliser les paramètres par défaut, il n'est plus nécessaire de faire l'opération à l'intérieur du corps de la fonction, il suffit de déclarer que la valeur par défaut pour `b` est 1 dans la signature de la fonction : -<pre class="brush: js">function multiplier(a, b = 1) { +```js +function multiplier(a, b = 1) { return a*b; } -multiplier(5); // 5</pre> +multiplier(5); // 5 +``` -<p>Pour plus de détails, voir <a href="/fr/docs/Web/JavaScript/Reference/Fonctions/Valeurs_par_défaut_des_arguments">la page sur les paramètres par défaut</a> dans la référence.</p> +Pour plus de détails, voir [la page sur les paramètres par défaut](/fr/docs/Web/JavaScript/Reference/Fonctions/Valeurs_par_défaut_des_arguments) dans la référence. -<h3 id="Les_paramètres_du_reste">Les paramètres du reste</h3> +### Les paramètres du reste -<p>La syntaxe des <a href="/fr/docs/Web/JavaScript/Reference/Fonctions/paramètres_du_reste">paramètres du reste</a> permet de représenter un nombre indéfini d'arguments contenus dans un tableau. Dans l'exemple suivant, on utilise les paramètres du reste pour collecter les arguments à partir du deuxième et jusqu'au dernier. Ces arguments sont multipliés par le premier. Dans cet exemple, on utilise une fonction fléchée, concept qui est présenté et illustré dans la section qui suit.</p> +La syntaxe des [paramètres du reste](/fr/docs/Web/JavaScript/Reference/Fonctions/paramètres_du_reste) permet de représenter un nombre indéfini d'arguments contenus dans un tableau. Dans l'exemple suivant, on utilise les paramètres du reste pour collecter les arguments à partir du deuxième et jusqu'au dernier. Ces arguments sont multipliés par le premier. Dans cet exemple, on utilise une fonction fléchée, concept qui est présenté et illustré dans la section qui suit. -<pre class="brush: js">function multiplier(facteur, ...lesArgs) { - return lesArgs.map(x => facteur * x); +```js +function multiplier(facteur, ...lesArgs) { + return lesArgs.map(x => facteur * x); } var arr = multiplier(2, 1, 2, 3); -console.log(arr); // [2, 4, 6]</pre> +console.log(arr); // [2, 4, 6] +``` + +## Fonctions fléchées -<h2 id="Fonctions_fléchées">Fonctions fléchées</h2> +[Une expression de fonction fléchée](/fr/docs/Web/JavaScript/Reference/Fonctions/Fonctions_fléchées) permet d'utiliser une syntaxe plus concise que les expressions de fonctions classiques. Une telle fonction ne possède alors pas de valeur propre pour [`this`](/fr/docs/Web/JavaScript/Reference/Opérateurs/L_opérateur_this), [`arguments`](/fr/docs/Web/JavaScript/Reference/Fonctions/arguments), [`super`](/fr/docs/Web/JavaScript/Reference/Opérateurs/super) ou [`new.target`](/fr/docs/Web/JavaScript/Reference/Opérateurs/new.target). Les fonctions fléchées sont nécessairement anonymes. -<p><a href="/fr/docs/Web/JavaScript/Reference/Fonctions/Fonctions_fléchées">Une expression de fonction fléchée</a> permet d'utiliser une syntaxe plus concise que les expressions de fonctions classiques. Une telle fonction ne possède alors pas de valeur propre pour <code><a href="/fr/docs/Web/JavaScript/Reference/Opérateurs/L_opérateur_this">this</a></code>, <code><a href="/fr/docs/Web/JavaScript/Reference/Fonctions/arguments">arguments</a></code>, <code><a href="/fr/docs/Web/JavaScript/Reference/Opérateurs/super">super</a></code> ou <code><a href="/fr/docs/Web/JavaScript/Reference/Opérateurs/new.target">new.target</a></code>. Les fonctions fléchées sont nécessairement anonymes.</p> +Les fonctions fléchées ont été introduites pour deux raisons principales : une syntaxe plus courte et l'absence de `this` rattaché à la fonction. Voir aussi [ce billet sur tech.mozfr.org sur les fonctions fléchées](https://tech.mozfr.org/post/2015/06/10/ES6-en-details-%3A-les-fonctions-flechees). -<p>Les fonctions fléchées ont été introduites pour deux raisons principales : une syntaxe plus courte et l'absence de <code>this</code> rattaché à la fonction. Voir aussi <a href="https://tech.mozfr.org/post/2015/06/10/ES6-en-details-%3A-les-fonctions-flechees">ce billet sur tech.mozfr.org sur les fonctions fléchées</a>.</p> -<p> </p> -<p> </p> -<h3 id="Concision_de_la_syntaxe">Concision de la syntaxe</h3> -<p>Dans certaines constructions fonctionnelles, on peut apprécier une syntaxe courte. Par exemple, si on compare les deux dernières lignes de ce fragment de code :</p> +### Concision de la syntaxe -<pre class="brush: js">var a = [ +Dans certaines constructions fonctionnelles, on peut apprécier une syntaxe courte. Par exemple, si on compare les deux dernières lignes de ce fragment de code : + +```js +var a = [ "Hydrogen", "Helium", "Lithium", @@ -563,14 +602,16 @@ console.log(arr); // [2, 4, 6]</pre> var a2 = a.map(function(s){ return s.length }); console.log(a2); // affiche [8, 6, 7, 9] -var a3 = a.map( s => s.length ); -console.log(a3); // affiche [8, 6, 7, 9]</pre> +var a3 = a.map( s => s.length ); +console.log(a3); // affiche [8, 6, 7, 9] +``` -<h3 id="Pas_de_this_distinct">Pas de <code>this</code> distinct</h3> +### Pas de `this` distinct -<p>Avant les fonctions fléchées, chaque nouvelle fonction définissait sa propre valeur <code><a href="/fr/docs/Web/JavaScript/Reference/Opérateurs/L_opérateur_this">this</a></code> (un nouvel objet dans le cas d'un constructeur, <code>undefined</code> lors des appels en <a href="/fr/docs/Web/JavaScript/Reference/Strict_mode">mode strict</a>, l'objet courant dans le cas d'une méthode, etc.). Cela pouvait poser quelques problèmes avec un style de programmation orienté objet.</p> +Avant les fonctions fléchées, chaque nouvelle fonction définissait sa propre valeur [`this`](/fr/docs/Web/JavaScript/Reference/Opérateurs/L_opérateur_this) (un nouvel objet dans le cas d'un constructeur, `undefined` lors des appels en [mode strict](/fr/docs/Web/JavaScript/Reference/Strict_mode), l'objet courant dans le cas d'une méthode, etc.). Cela pouvait poser quelques problèmes avec un style de programmation orienté objet. -<pre class="brush: js">function Personne() { +```js +function Personne() { // Le constructeur Personne() utilise `this` comme lui-même. this.âge = 0; @@ -582,11 +623,13 @@ console.log(a3); // affiche [8, 6, 7, 9]</pre> }, 1000); } -var p = new Personne();</pre> +var p = new Personne(); +``` -<p>Avec ECMAScript 3/5, ce problème fut résolu avec l'affectation de la valeur de <code>this</code> dans une variable a variable that could be closed over.</p> +Avec ECMAScript 3/5, ce problème fut résolu avec l'affectation de la valeur de `this` dans une variable a variable that could be closed over. -<pre class="brush: js">function Personne() { +```js +function Personne() { var self = this; // Certains utilisent `that`, d'autres `self`. // On utilisera l'un des deux et on pas // l'autre pour être cohérent. @@ -597,75 +640,52 @@ var p = new Personne();</pre> // qui est bien la valeur attendue liée à l'objet. self.âge++; }, 1000); -}</pre> +} +``` -<p>On aurait aussi pu créer une fonction liée afin que la « bonne » valeur de <code>this</code> soit passée à la fonction <code>grandir()</code>.</p> +On aurait aussi pu créer une fonction liée afin que la « bonne » valeur de `this` soit passée à la fonction `grandir()`. -<p>Les fonctions fléchées capturent la valeur de <code>this</code> dans le contexte englobant et cela permet de manipuler la valeur pertinente ici :</p> +Les fonctions fléchées capturent la valeur de `this` dans le contexte englobant et cela permet de manipuler la valeur pertinente ici : -<pre class="brush: js">function Personne(){ +```js +function Personne(){ this.âge = 0; - setInterval(() => { + setInterval(() => { this.âge++; // this fait référence à l'objet personne }, 1000); } -var p = new Personne();</pre> - -<h2 id="Fonctions_prédéfinies">Fonctions prédéfinies</h2> - -<p>JavaScript possède plusieurs fonctions natives, disponibles au plus haut niveau :</p> - -<dl> - <dt>{{jsxref("Objets_globaux/eval","eval()")}}</dt> - <dd> - <p>La fonction <code><strong>eval()</strong></code> permet d'évaluer du code JavaScript contenu dans une chaîne de caractères.</p> - </dd> - <dt>{{jsxref("Objets_globaux/uneval","uneval()")}} {{non-standard_inline}}</dt> - <dd> - <p>La fonction <code><strong>uneval()</strong></code> crée une représentation sous la forme d'une chaîne de caractères pour le code source d'un objet.</p> - </dd> - <dt>{{jsxref("Objets_globaux/isFinite","isFinite()")}}</dt> - <dd> - <p>La fonction <code><strong>isFinite()</strong></code> détermine si la valeur passée est un nombre fini. Si nécessaire, le paramètre sera converti en un nombre.</p> - </dd> - <dt>{{jsxref("Objets_globaux/isNaN","isNaN()")}}</dt> - <dd> - <p>La fonction <code><strong>isNaN()</strong></code> détermine si une valeur est {{jsxref("NaN")}} ou non. Note : On pourra également utiliser {{jsxref("Number.isNaN()")}} défini avec ECMAScript 6 ou utiliser <code><a href="/fr/docs/Web/JavaScript/Reference/Opérateurs/L_opérateur_typeof">typeof</a></code> afin de déterminer si la valeur est <em><strong>N</strong>ot-<strong>A</strong>-<strong>N</strong>umber</em>.</p> - </dd> - <dt>{{jsxref("Objets_globaux/parseFloat","parseFloat()")}}</dt> - <dd> - <p>La fonction <code><strong>parseFloat()</strong></code> convertit une chaîne de caractères en un nombre flottant.</p> - </dd> - <dt>{{jsxref("Objets_globaux/parseInt","parseInt()")}}</dt> - <dd> - <p>La fonction <code><strong>parseInt()</strong></code> convertit une chaîne de caractères et renvoie un entier dans la base donnée.</p> - </dd> - <dt>{{jsxref("Objets_globaux/decodeURI","decodeURI()")}}</dt> - <dd> - <p>La fonction <code><strong>decodeURI()</strong></code> décode un Uniform Resource Identifier (URI) créé par {{jsxref("Objets_globaux/encodeURI","encodeURI()")}} ou une méthode similaire.</p> - </dd> - <dt>{{jsxref("Objets_globaux/decodeURIComponent","decodeURIComponent()")}}</dt> - <dd> - <p>La fonction <code><strong>decodeURIComponent()</strong></code> décode un composant d'un Uniform Resource Identifier (URI) créé par {{jsxref("Objets_globaux/encodeURIComponent","encodeURIComponent")}} ou une méthode similaire.</p> - </dd> - <dt>{{jsxref("Objets_globaux/encodeURI","encodeURI()")}}</dt> - <dd> - <p>La fonction <code><strong>encodeURI()</strong></code> encode un Uniform Resource Identifier (URI) en remplaçant chaque exemplaire de certains caractères par un, deux, trois voire quatre séquences d'échappement représentant l'encodage UTF-8 du caractères (quatre séquences seront utilisées uniquement lorsque le caractère est composé d'une paire de deux demi-codets).</p> - </dd> - <dt>{{jsxref("Objets_globaux/encodeURIComponent","encodeURIComponent()")}}</dt> - <dd> - <p>La fonction <code><strong>encodeURIComponent()</strong></code> encode un composant d'un Uniform Resource Identifier (URI) en remplaçant chaque exemplaire de certains caractères par un, deux, trois voire quatre séquences d'échappement représentant l'encodage UTF-8 du caractères (quatre séquences seront utilisées uniquement lorsque le caractère est composé d'une paire de deux demi-codets).</p> - </dd> - <dt>{{jsxref("Objets_globaux/escape","escape()")}} {{deprecated_inline}}</dt> - <dd> - <p>La fonction dépréciée <code><strong>escape()</strong></code> calcule une nouvelle chaîne de caractères pour laquelle certains caractères ont été remplacés par leur séquence d'échappement hexadécimale. Les fonctions {{jsxref("Objets_globaux/encodeURI","encodeURI()")}} ou {{jsxref("Objets_globaux/encodeURIComponent","encodeURIComponent()")}} doivent être utilisées à la place.</p> - </dd> - <dt>{{jsxref("Objets_globaux/unescape","unescape()")}} {{deprecated_inline}}</dt> - <dd> - <p>La fonction dépréciée <code><strong>unescape()</strong></code> calcule une nouvelle chaîne de caractères pour laquelle les séquences d'échappement hexadécimales sont remplacées par les caractères qu'elles représentent. Les séquences d'échappement introduites peuvent provenir d'une fonction telle que {{jsxref("Objets_globaux/escape","escape()")}}. <code>unescape</code> est dépréciée et doit être remplacée par {{jsxref("Objets_globaux/decodeURI","decodeURI()")}} ou {{jsxref("Objets_globaux/decodeURIComponent","decodeURIComponent()")}}.</p> - </dd> -</dl> - -<p>{{PreviousNext("Web/JavaScript/Guide/Boucles_et_it%C3%A9ration", "Web/JavaScript/Guide/Expressions_et_Op%C3%A9rateurs")}}</p> +var p = new Personne(); +``` + +## Fonctions prédéfinies + +JavaScript possède plusieurs fonctions natives, disponibles au plus haut niveau : + +- {{jsxref("Objets_globaux/eval","eval()")}} + - : La fonction **`eval()`** permet d'évaluer du code JavaScript contenu dans une chaîne de caractères. +- {{jsxref("Objets_globaux/uneval","uneval()")}} {{non-standard_inline}} + - : La fonction **`uneval()`** crée une représentation sous la forme d'une chaîne de caractères pour le code source d'un objet. +- {{jsxref("Objets_globaux/isFinite","isFinite()")}} + - : La fonction **`isFinite()`** détermine si la valeur passée est un nombre fini. Si nécessaire, le paramètre sera converti en un nombre. +- {{jsxref("Objets_globaux/isNaN","isNaN()")}} + - : La fonction **`isNaN()`** détermine si une valeur est {{jsxref("NaN")}} ou non. Note : On pourra également utiliser {{jsxref("Number.isNaN()")}} défini avec ECMAScript 6 ou utiliser [`typeof`](/fr/docs/Web/JavaScript/Reference/Opérateurs/L_opérateur_typeof) afin de déterminer si la valeur est **\*N**ot-**A**-**N**umber\*. +- {{jsxref("Objets_globaux/parseFloat","parseFloat()")}} + - : La fonction **`parseFloat()`** convertit une chaîne de caractères en un nombre flottant. +- {{jsxref("Objets_globaux/parseInt","parseInt()")}} + - : La fonction **`parseInt()`** convertit une chaîne de caractères et renvoie un entier dans la base donnée. +- {{jsxref("Objets_globaux/decodeURI","decodeURI()")}} + - : La fonction **`decodeURI()`** décode un Uniform Resource Identifier (URI) créé par {{jsxref("Objets_globaux/encodeURI","encodeURI()")}} ou une méthode similaire. +- {{jsxref("Objets_globaux/decodeURIComponent","decodeURIComponent()")}} + - : La fonction **`decodeURIComponent()`** décode un composant d'un Uniform Resource Identifier (URI) créé par {{jsxref("Objets_globaux/encodeURIComponent","encodeURIComponent")}} ou une méthode similaire. +- {{jsxref("Objets_globaux/encodeURI","encodeURI()")}} + - : La fonction **`encodeURI()`** encode un Uniform Resource Identifier (URI) en remplaçant chaque exemplaire de certains caractères par un, deux, trois voire quatre séquences d'échappement représentant l'encodage UTF-8 du caractères (quatre séquences seront utilisées uniquement lorsque le caractère est composé d'une paire de deux demi-codets). +- {{jsxref("Objets_globaux/encodeURIComponent","encodeURIComponent()")}} + - : La fonction **`encodeURIComponent()`** encode un composant d'un Uniform Resource Identifier (URI) en remplaçant chaque exemplaire de certains caractères par un, deux, trois voire quatre séquences d'échappement représentant l'encodage UTF-8 du caractères (quatre séquences seront utilisées uniquement lorsque le caractère est composé d'une paire de deux demi-codets). +- {{jsxref("Objets_globaux/escape","escape()")}} {{deprecated_inline}} + - : La fonction dépréciée **`escape()`** calcule une nouvelle chaîne de caractères pour laquelle certains caractères ont été remplacés par leur séquence d'échappement hexadécimale. Les fonctions {{jsxref("Objets_globaux/encodeURI","encodeURI()")}} ou {{jsxref("Objets_globaux/encodeURIComponent","encodeURIComponent()")}} doivent être utilisées à la place. +- {{jsxref("Objets_globaux/unescape","unescape()")}} {{deprecated_inline}} + - : La fonction dépréciée **`unescape()`** calcule une nouvelle chaîne de caractères pour laquelle les séquences d'échappement hexadécimales sont remplacées par les caractères qu'elles représentent. Les séquences d'échappement introduites peuvent provenir d'une fonction telle que {{jsxref("Objets_globaux/escape","escape()")}}. `unescape` est dépréciée et doit être remplacée par {{jsxref("Objets_globaux/decodeURI","decodeURI()")}} ou {{jsxref("Objets_globaux/decodeURIComponent","decodeURIComponent()")}}. + +{{PreviousNext("Web/JavaScript/Guide/Boucles_et_it%C3%A9ration", "Web/JavaScript/Guide/Expressions_et_Op%C3%A9rateurs")}} |