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 JavaScript — TypeScript — JavaScript asynchrone