iducationducation
IndexArticlesFormationsProfilOutilsBibliothech
N°014 — 2026
Navigation
01Index02Articles03Formations04Profil05Outils06Bibliothech
N°014 — 2026
iducationducation
IndexArticlesFormationsProfilOutilsBibliothech
N°014 — 2026
Navigation
01Index02Articles03Formations04Profil05Outils06Bibliothech
N°014 — 2026
Formations
JavaScript · Débutant

JavaScript

Apprendre JavaScript de zéro jusqu'au niveau expert : syntaxe moderne, DOM, asynchrone et event loop, modules, prototypes, métaprogrammation, performance et mémoire.

JavaScript ES2025Node.jsDOMVitestVite
01Introduction et environnement02Variables, types et coercition03Conditions et boucles04Fonctions, portée et closures05Objets, tableaux, Map et Set06Le DOM et les événements07Asynchrone : callbacks, promesses, async/await et event loop08Modules, npm, outillage et tests09Prototypes, classes et this10Itérateurs, générateurs, Symbol, Proxy et métaprogrammation11Niveau expert : moteur, performance, mémoire et architecture
Chapitre 4·40 min

Fonctions, portée et closures

En JavaScript, les fonctions sont des valeurs. On les stocke dans des variables, on les passe en argument, on les renvoie. Toute l'architecture du langage — callbacks, événements, promesses, React — repose sur ce principe. Et sur un deuxième : la closure, qu'on verra en fin de chapitre.

Trois façons de déclarer

// Déclaration : hoistée, utilisable avant sa définition
function additionner(a, b) {
  return a + b
}
 
// Expression
const soustraire = function (a, b) {
  return a - b
}
 
// Fonction fléchée
const multiplier = (a, b) => a * b
const carre = n => n * n
const creerUser = nom => ({ nom, cree: Date.now() })   // parenthèses pour renvoyer un objet

Les fléchées ont un corps implicite quand il n'y a pas d'accolades. Elles diffèrent aussi par leur gestion de this, détaillée au chapitre 9.

Paramètres

function saluer(nom = 'inconnu', { majuscules = false, ponctuation = '!' } = {}) {
  const msg = `Bonjour ${nom}${ponctuation}`
  return majuscules ? msg.toUpperCase() : msg
}
 
saluer()                                    // 'Bonjour inconnu!'
saluer('Ada', { majuscules: true })         // 'BONJOUR ADA!'

Passer un objet d'options déstructuré est le pattern standard dès qu'une fonction a plus de deux paramètres. L'appel devient lisible et l'ordre ne compte plus.

Paramètres rest et spread :

function somme(...nombres) {
  return nombres.reduce((acc, n) => acc + n, 0)
}
 
somme(1, 2, 3)          // 6
const valeurs = [4, 5]
somme(...valeurs)       // 9
Math.max(...valeurs)    // 5

Portée

JavaScript a une portée lexicale : une fonction voit les variables de l'endroit où elle est écrite, pas de l'endroit où elle est appelée.

const x = 'global'
 
function externe() {
  const x = 'externe'
  function interne() {
    return x
  }
  return interne
}
 
externe()()   // 'externe'

let et const ont une portée de bloc ({}), var une portée de fonction :

if (true) {
  var a = 1
  let b = 2
}
a   // 1
b   // ReferenceError

Closures

Une closure est une fonction qui garde l'accès aux variables de sa portée de création, même après que cette portée a fini de s'exécuter.

function creerCompteur() {
  let n = 0
  return {
    incrementer: () => ++n,
    valeur: () => n,
  }
}
 
const c = creerCompteur()
c.incrementer()
c.incrementer()
c.valeur()   // 2
c.n          // undefined — n est privée

n survit parce que les fonctions renvoyées la référencent. C'est le moyen le plus ancien d'avoir des variables privées en JavaScript.

Cas d'usage : fabriques de fonctions

const multiplierPar = facteur => n => n * facteur
const double = multiplierPar(2)
const triple = multiplierPar(3)
double(5)   // 10

Cas d'usage : debounce

Retarder l'exécution d'une fonction jusqu'à ce que l'utilisateur arrête de taper :

function debounce(fn, delai = 300) {
  let timer
  return (...args) => {
    clearTimeout(timer)
    timer = setTimeout(() => fn(...args), delai)
  }
}
 
const rechercher = debounce(q => fetch(`/api/search?q=${encodeURIComponent(q)}`), 250)
input.addEventListener('input', e => rechercher(e.target.value))

timer est partagé entre tous les appels grâce à la closure.

Cas d'usage : mémoïsation

function memoize(fn) {
  const cache = new Map()
  return arg => {
    if (!cache.has(arg)) cache.set(arg, fn(arg))
    return cache.get(arg)
  }
}
 
const fib = memoize(n => (n < 2 ? n : fib(n - 1) + fib(n - 2)))
fib(90)   // instantané

Fonctions d'ordre supérieur

Une fonction qui prend ou renvoie une fonction. Les méthodes de tableau en sont l'exemple le plus courant :

const produits = [
  { nom: 'Clavier', prix: 80, stock: 3 },
  { nom: 'Souris', prix: 25, stock: 0 },
  { nom: 'Écran', prix: 220, stock: 5 },
]
 
const valeurStock = produits
  .filter(p => p.stock > 0)
  .map(p => p.prix * p.stock)
  .reduce((total, v) => total + v, 0)
// 1340

Composition :

const pipe = (...fns) => x => fns.reduce((v, f) => f(v), x)
 
const slugifier = pipe(
  s => s.trim(),
  s => s.toLowerCase(),
  s => s.normalize('NFD').replace(/[̀-ͯ]/g, ''),
  s => s.replace(/[^a-z0-9]+/g, '-'),
  s => s.replace(/^-|-$/g, ''),
)
 
slugifier('  Élégant Titre, Été 2026 ')   // 'elegant-titre-ete-2026'

Les motifs utilisés ici sont détaillés dans le guide des expressions régulières.

Fonctions pures

Une fonction pure renvoie toujours le même résultat pour les mêmes entrées et ne modifie rien à l'extérieur. Elle est triviale à tester et à mémoïser.

// Impure : modifie l'argument
function ajouterTag(article, tag) {
  article.tags.push(tag)
  return article
}
 
// Pure : renvoie une nouvelle version
const ajouterTagPur = (article, tag) => ({ ...article, tags: [...article.tags, tag] })

IIFE

Une fonction exécutée immédiatement. Historiquement utilisée pour isoler des variables avant les modules :

const config = (() => {
  const env = process.env.NODE_ENV ?? 'development'
  return { env, debug: env !== 'production' }
})()

Exercice : throttle

Écrire throttle(fn, ms) qui exécute fn au plus une fois toutes les ms millisecondes (utile pour le scroll).

function throttle(fn, ms) {
  let dernier = 0
  return (...args) => {
    const maintenant = Date.now()
    if (maintenant - dernier >= ms) {
      dernier = maintenant
      fn(...args)
    }
  }
}
 
window.addEventListener('scroll', throttle(() => console.log(scrollY), 100))

Retenez la closure : une fonction emporte avec elle les variables qu'elle voit à sa création. Debounce, mémoïsation, modules, hooks React — tous reposent sur ce seul mécanisme.

Précédent
Conditions et boucles
Suivant
Objets, tableaux, Map et Set

Développeur fullstack passionné. J'apprends en construisant et je documente tout — front, back, outils. Le code s'apprend mieux en public.

Naviguer

IndexTous les articlesFormationsProfilOutilsBibliothech

Ailleurs

GitHub RSS

Newsletter

Les articles, libs et découvertes. Une fois par semaine, pas plus.

© 2026 William LoreeConçu & codé à la main