Publie le 24 mars 2026 Par

JavaScript ES2025 : les nouveautés qui changent vraiment la façon de coder

JavaScript évolue chaque année via le processus TC39. ES2025 apporte des fonctionnalités qui simplifient du code que vous écrivez quotidiennement. Plutôt qu’une liste exhaustive, ce guide se concentre sur ce qui change vraiment votre façon de coder — avec des exemples concrets avant/après.

Iterator Helpers — traiter les séquences de façon lazy

Les méthodes d’itérateurs (.map(), .filter(), .take()) peuvent maintenant être chaînées directement sur n’importe quel itérable sans créer des tableaux intermédiaires :

// Avant ES2025 — créait des tableaux intermédiaires
const result = [...someSet]
  .filter(x => x > 0)
  .map(x => x * 2)
  .slice(0, 5)

// ES2025 — lazy, pas de tableau intermédiaire
const result = someSet.values()
  .filter(x => x > 0)
  .map(x => x * 2)
  .take(5)
  .toArray()

// Fonctionne sur Set, Map, générateurs, ou n'importe quel itérable
const topProducts = productMap.values()
  .filter(p => p.inStock)
  .map(p => ({ id: p.id, name: p.name }))
  .take(10)
  .toArray()

Promise.try — simplifier le code sync/async mixte

// Avant — wrapper try/catch pour garantir une Promise
function maybeAsync(value: unknown) {
  try {
    const result = couldThrowSync(value)
    return Promise.resolve(result)
  } catch (err) {
    return Promise.reject(err)
  }
}

// ES2025 — Promise.try gère les deux cas
function maybeAsync(value: unknown) {
  return Promise.try(() => couldThrowSync(value))
}

// Cas d'usage réel : handlers qui peuvent être sync ou async
router.get('/user', (req, res) => {
  Promise.try(() => getUserFromCache(req.params.id) || fetchUser(req.params.id))
    .then(user => res.json(user))
    .catch(err => res.status(500).json({ error: err.message }))
})

Object.groupBy et Map.groupBy

Disponible depuis ES2024 mais maintenant largement supporté, Object.groupBy remplace le pattern reduce-pour-grouper :

const products = [
  { name: 'Laptop', category: 'electronics', price: 999 },
  { name: 'Phone', category: 'electronics', price: 699 },
  { name: 'Desk', category: 'furniture', price: 299 },
]

// Avant — reduce verbeux
const grouped = products.reduce((acc, p) => {
  (acc[p.category] = acc[p.category] || []).push(p)
  return acc
}, {})

// ES2024/2025 — direct
const grouped = Object.groupBy(products, p => p.category)
// { electronics: [{...}, {...}], furniture: [{...}] }

// Map.groupBy pour des clés non-string
const groupedByPrice = Map.groupBy(products, p =>
  p.price > 500 ? 'premium' : 'standard'
)

Temporal API — enfin une vraie gestion des dates

La Temporal API (stage 3 en ES2025, disponible via polyfill) remplace le catastrophique objet Date :

// Avant — les dates JavaScript sont notoires pour leurs bugs
const d = new Date('2026-03-15')
d.setMonth(d.getMonth() + 1) // mutation, timezone hell

// Temporal — immutable, timezone-aware
const date = Temporal.PlainDate.from('2026-03-15')
const nextMonth = date.add({ months: 1 }) // nouveau objet, pas de mutation
// 2026-04-15

// Calcul de durée
const start = Temporal.PlainDate.from('2026-01-01')
const end = Temporal.PlainDate.from('2026-03-24')
const duration = start.until(end)
// { days: 82 }

// Avec timezone
const meeting = Temporal.ZonedDateTime.from({
  timeZone: 'Europe/Paris',
  year: 2026, month: 3, day: 24,
  hour: 14, minute: 30,
})

Pattern matching — la proposition à surveiller

Pas encore en ES2025 mais en stage 2 : le pattern matching, qui remplacera les chaînes de if/switch complexes. À surveiller pour 2026-2027.

// Proposition stage 2 — pas encore dispo nativement
const result = match(response) {
  when ({ status: 200, data }) => processData(data),
  when ({ status: 404 }) => showNotFound(),
  when ({ status: 500 }) => showServerError(),
  else => showUnknownError(),
}

Ce qui est stabilisé et dispo maintenant

  • Array.at(-1) — accéder au dernier élément sans arr[arr.length - 1]
  • structuredClone() — cloner profondément un objet sans JSON.parse/JSON.stringify
  • Object.hasOwn() — remplace Object.prototype.hasOwnProperty.call()
  • Error.cause — chaîner les erreurs avec contexte
  • Array.toSorted(), toReversed(), toSpliced() — versions non-mutantes des méthodes de tableau
// Exemples pratiques
const last = items.at(-1)                    // dernier élément
const clone = structuredClone(complexObject) // deep clone propre
const sorted = items.toSorted((a, b) => a.price - b.price) // items original intact

// Error chaining
try {
  await fetchData()
} catch (cause) {
  throw new Error('Impossible de charger les données', { cause })
  // err.cause contient l'erreur originale
}

Offres développeur JavaScript

Des postes pour développeurs JavaScript qui restent à jour sur l’évolution du langage.

À lire aussi : Apprendre JavaScriptTypeScriptJavaScript asynchrone

Categories : JavaScript & React