# Chapitre 2 : Fonctions ## Arrow Functions Les arrow functions sont une syntaxe raccourcie pour les fonctions. Elles sont omniprésentes en React. ### Syntaxe de base ```javascript // Fonction traditionnelle function add(a, b) { return a + b; } // Arrow function équivalente const add = (a, b) => { return a + b; }; // Syntaxe courte (return implicite) const add = (a, b) => a + b; ``` ### Règles de syntaxe ```javascript // Un seul paramètre : parenthèses optionnelles const double = x => x * 2; const double = (x) => x * 2; // équivalent // Zéro paramètre : parenthèses obligatoires const sayHello = () => "Hello"; // Plusieurs paramètres : parenthèses obligatoires const add = (a, b) => a + b; // Corps multi-lignes : accolades + return explicite const calculate = (a, b) => { const sum = a + b; const product = a * b; return { sum, product }; }; // Retourner un objet directement : parenthèses autour const createUser = (name) => ({ name, createdAt: new Date() }); // Sans parenthèses, JS pense que {} est le corps de la fonction! ``` ### Comparaison avec PHP ```php // PHP - fonction anonyme $add = function($a, $b) { return $a + $b; }; // PHP 7.4+ - arrow function (expression unique) $add = fn($a, $b) => $a + $b; ``` ```javascript // JavaScript - arrow function const add = (a, b) => a + b; ``` ## Différence avec les fonctions traditionnelles Les arrow functions ont une différence majeure : elles **n'ont pas leur propre `this`**. ```javascript // Problème avec fonction traditionnelle const obj = { name: "Jean", greet: function() { setTimeout(function() { console.log(this.name); // undefined! 'this' a changé }, 1000); } }; // Solution avec arrow function const obj = { name: "Jean", greet: function() { setTimeout(() => { console.log(this.name); // "Jean" - arrow conserve le 'this' }, 1000); } }; ``` En React, cela simplifie beaucoup de choses (nous y reviendrons). ## Paramètres par défaut ```javascript // Valeur par défaut si le paramètre n'est pas fourni function greet(name = "Visiteur") { return `Bonjour ${name}`; } greet(); // "Bonjour Visiteur" greet("Jean"); // "Bonjour Jean" // Avec arrow function const greet = (name = "Visiteur") => `Bonjour ${name}`; // Paramètre par défaut utilisant un autre paramètre const createUser = (name, role = "user", id = Date.now()) => ({ name, role, id }); ``` ### Comparaison avec PHP ```php // PHP function greet($name = "Visiteur") { return "Bonjour $name"; } ``` ## Fonctions de premier ordre (Callbacks) En JavaScript, les fonctions sont des valeurs. On peut les : - Stocker dans des variables - Passer en argument à d'autres fonctions - Retourner depuis des fonctions ### Passer une fonction en argument ```javascript // Fonction qui prend une autre fonction en paramètre function executeWithLogging(fn, value) { console.log(`Exécution avec: ${value}`); const result = fn(value); console.log(`Résultat: ${result}`); return result; } const double = x => x * 2; executeWithLogging(double, 5); // "Exécution avec: 5" // "Résultat: 10" ``` ### Méthodes de tableau avec callbacks Ces méthodes sont **essentielles** en React : ```javascript const numbers = [1, 2, 3, 4, 5]; // map - transformer chaque élément const doubled = numbers.map(n => n * 2); // [2, 4, 6, 8, 10] // filter - garder les éléments qui passent le test const evens = numbers.filter(n => n % 2 === 0); // [2, 4] // find - trouver le premier élément const firstBig = numbers.find(n => n > 3); // 4 // some - au moins un élément passe le test const hasEven = numbers.some(n => n % 2 === 0); // true // every - tous les éléments passent le test const allPositive = numbers.every(n => n > 0); // true // reduce - réduire à une seule valeur const sum = numbers.reduce((acc, n) => acc + n, 0); // 15 ``` ### Usage en React ```javascript // Afficher une liste const users = [ { id: 1, name: "Jean" }, { id: 2, name: "Marie" } ]; // Dans un composant React return ( ); // Filtrer et afficher const activeUsers = users.filter(u => u.active); return ( ); ``` ### Comparaison avec PHP ```php // PHP $doubled = array_map(fn($n) => $n * 2, $numbers); $evens = array_filter($numbers, fn($n) => $n % 2 === 0); $sum = array_reduce($numbers, fn($acc, $n) => $acc + $n, 0); ``` ```javascript // JavaScript - méthodes chaînables const result = numbers .filter(n => n > 2) .map(n => n * 2) .reduce((acc, n) => acc + n, 0); ``` ## Shorthand Property Names Quand le nom de la propriété est le même que le nom de la variable : ```javascript const name = "Jean"; const age = 30; // SANS shorthand const user = { name: name, age: age }; // AVEC shorthand const user = { name, age }; // { name: "Jean", age: 30 } // Mélange const user = { name, age, city: "Paris" // pas de shorthand ici }; ``` ## Shorthand Method Names ```javascript // SANS shorthand const obj = { greet: function() { return "Hello"; } }; // AVEC shorthand const obj = { greet() { return "Hello"; } }; ``` ## Exercices ### Exercice 1 : Arrow functions Convertir en arrow functions : ```javascript function multiply(a, b) { return a * b; } function isEven(n) { return n % 2 === 0; } function createGreeting(name) { return { message: `Bonjour ${name}`, timestamp: Date.now() }; } ``` **Solution :** ```javascript const multiply = (a, b) => a * b; const isEven = n => n % 2 === 0; const createGreeting = name => ({ message: `Bonjour ${name}`, timestamp: Date.now() }); ``` ### Exercice 2 : Méthodes de tableau Avec ce tableau d'utilisateurs : ```javascript const users = [ { id: 1, name: "Jean", age: 25, active: true }, { id: 2, name: "Marie", age: 30, active: false }, { id: 3, name: "Pierre", age: 35, active: true }, { id: 4, name: "Sophie", age: 28, active: true } ]; ``` 1. Obtenir un tableau des noms uniquement 2. Filtrer les utilisateurs actifs de plus de 26 ans 3. Calculer la somme des âges **Solution :** ```javascript // 1. Noms const names = users.map(u => u.name); // ["Jean", "Marie", "Pierre", "Sophie"] // 2. Actifs > 26 ans const filtered = users.filter(u => u.active && u.age > 26); // [{ id: 3, ... }, { id: 4, ... }] // 3. Somme des âges const totalAge = users.reduce((sum, u) => sum + u.age, 0); // 118 ``` ## Points clés à retenir 1. **Arrow functions** : `(params) => expression` ou `(params) => { statements }` 2. **Return implicite** : sans accolades, la valeur est retournée automatiquement 3. **Retourner un objet** : `() => ({ key: value })` (parenthèses obligatoires) 4. **Callbacks** : les fonctions peuvent être passées en argument 5. **map, filter, reduce** : méthodes essentielles pour manipuler des tableaux 6. **Shorthand** : `{ name }` équivaut à `{ name: name }` [[:15_training:module1-javascript-es6:variables-scope|← Chapitre précédent]] | [[:15_training:module1-javascript-es6:start|Retour au module]] | [[:15_training:module1-javascript-es6:asynchrone|Chapitre suivant : Asynchrone →]]