---
title: "Chapitre 2 : Fonctions"
weight: 320
---

# 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 (
    <ul>
        {users.map(user => (
            <li key={user.id}>{user.name}</li>
        ))}
    </ul>
);

// Filtrer et afficher
const activeUsers = users.filter(u => u.active);
return (
    <ul>
        {activeUsers.map(user => (
            <li key={user.id}>{user.name}</li>
        ))}
    </ul>
);
```

### 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 }`

[← Chapitre précédent](/training/module1-javascript-es6/variables-scope) | [Retour au module](/training/module1-javascript-es6) | [Chapitre suivant : Asynchrone ->](/training/module1-javascript-es6/asynchrone)
