Accueil / Articles

Quatre API JavaScript intégrées qui remplacent les outils courants de Lodash

Comment Math.sumPrecise, Map.getOrInsert, Array.fromAsync ainsi que les outils d’itération remplacent les fonctions de Lodash, et quels sont les points à connaître concernant la précision et la concurrence.

Éditeur : REACTAPP.TOP4 min de lecture888 mots

Sources: The 4 ES2026 Features That Finally Replace Lodash

Installer Lodash était autrefois l’un des premiers étapes dans tout projet JavaScript : il additionnait des nombres, remplissait des tableaux avec des valeurs par défaut et permettait de chaîner des transformations différées. Les dernières éditions d’ECMAScript intègrent désormais des équivalents intégrés pour ces tâches, de sorte que cette dépendance n’est souvent qu’un fardeau supplémentaire. Ci-dessous sont présentées quatre API natives, ce qu’elles remplacent respectivement, ainsi que les cas où l’explication habituelle en une ligne est trompeuse.

Le support des moteurs pour ces nouvelles fonctionnalités est encore en cours de déploiement ; vérifiez donc les données de compatibilité de vos navigateurs et de votre version de Node.js avant d’installer un polyfill. Pour une étude plus approfondie, consultez les sept fonctionnalités natives de JavaScript qui remplacent les dépendances d’outils.

Math.sumPrecise() à la place de _.sum()

Les nombres en JavaScript sont des doubles IEEE 754, c’est pourquoi 0.1 + 0.2 donne 0.30000000000000004. _.sum() ne propose aucune protection : il s’agit d’une simple boucle utilisant l’opérateur +, ce qui signifie qu’il subit tous les arrondissements. Math.sumPrecise() prend un objet itérable et renvoie la somme comme si elle avait été calculée avec précision, en effectuant un arrondi une seule fois à la fin.

// ❌ The Legacy Lodash/Hack Way
const prices = [0.1, 0.2];
const total = _.sum(prices); // Still prone to precision errors without custom logic


// ✅ The ES2026 Native Standard
const exactTotal = Math.sumPrecise([0.1, 0.2]);
console.log(exactTotal); // 0.3 (Perfect precision)

Une correction à ce commentaire : 0.1 et 0.2 sont déjà imparfaits avant toute addition, et leur somme exacte se ronde à 0.30000000000000004 ; par conséquent, Math.sumPrecise([0.1, 0.2]) renvoie cette valeur et non 0.3. Ce que la méthode élimine, c’est l’erreur accumulée au fil de multiples additions : pour [1e20, 0.1, -1e20], une addition naïve donne 0 tandis que Math.sumPrecise renvoie 0.1. Il ne s’agit pas d’un type décimal, donc les montants financiers doivent être représentés en centimes entiers ou à l’aide d’une bibliothèque décimale. De plus, cette méthode lance une TypeError en cas de valeurs non numériques au lieu de les convertir.

Map.prototype.getOrInsert() à la place de has/set/get

Les outils de mise en cache et de regroupement suivent un schéma familier : on vérifie l’existence d’une clé, on stocke une valeur par défaut si elle est absente, puis on lit à nouveau la valeur. getOrInsert(key, defaultValue) effectue tout cela en une seule appelation, en retournant l’entrée existante ou en insérant et en retournant la valeur par défaut.

// ❌ The Legacy Way
const userCache = new Map();

function getUser(id) {
  if (!userCache.has(id)) {
    userCache.set(id, { status: 'pending' });
  }
  return userCache.get(id);
}




// ✅ The ES2026 Native Standard
const userCache = new Map();

function getUser(id) {
  // Checks for the key. If missing, inserts the fallback and returns it instantly.
  return userCache.getOrInsert(id, { status: 'pending' });
}

Notez que l’objet de remplacement est toujours créé à chaque appel, même lorsqu’il est ignoré. Si la valeur par défaut est coûteuse en ressources, utilisez getOrInsertComputed(key, callback), qui ne lance le callback que en cas d’absence de clé. Ces deux méthodes existent également dans WeakMap ; l’aspect Node.js est abordé dans Node.js 26 : Temporal, Map upserts et Undici 8.

Array.fromAsync() pour vider des itérateurs asynchrones

Récupérer un client API paginé ou un flux lisible dans un tableau signifiait auparavant utiliser une boucle manuelle for await...of pour y ajouter des éléments progressivement. Array.fromAsync() consomme un itérateur asynchrone, attend la fin du traitement de chaque élément et restitue un tableau ordinaire.

// The ES2026 Native Standard
async function fetchAllPages(asyncPaginationStream) {
  // Consumes the entire async stream and resolves into a flat array
  const allRecords = await Array.fromAsync(asyncPaginationStream);

  return allRecords;
}

Un deuxième argument optionnel permet de mapper chaque élément, et son résultat est également attendu, ce qui couvre le cas de la méthode asynchrone map. Il convient de se rappeler que les éléments sont traités séquentiellement, dans l’ordre. Cela convient aux flux et aux curseurs, mais ce n’est pas un substitut à Promise.all : si vous disposez de promesses indépendantes qui doivent s’exécuter en parallèle, Promise.all reste l’outil adapté. De plus, stocker un flux illimité en mémoire va à l’encontre de l’objectif même du streaming.

Aides pour les itérateurs plutôt que _.chain()

La raison principale de conserver Lodash est _.chain(), dont l’évaluation différée permet à des opérations comme map, filter et take-five sur 10 000 éléments de s’arrêter dès que cinq résultats sont obtenus. Les méthodes d’array, en revanche, agissent de manière immédiate : .map() crée un tableau intermédiaire complet, .filter() le parcourt à nouveau, et .slice() jette ensuite la majeure partie des résultats.

Les outils d’itération, standardisés dans ES2025, rendent cette approche différée nativement possible. .values() retourne un itérateur, et les méthodes map, filter ainsi que take sur cet itérateur extraient un élément à la fois jusqu’à ce que toArray() collecte les résultats.

// ❌ The Array Way (Inefficient: Maps and filters all 10,000 items)
const result = massiveArray
  .map(x => heavyComputation(x))
  .filter(x => x > 100)
  .slice(0, 5);



// ✅ The ES2026 Native Lazy Standard
const result = massiveArray
  .values() // Converts to an Iterator
  .map(x => heavyComputation(x))
  .filter(x => x > 100)
  .take(5) // Stops exactly when 5 items are found!
  .toArray();

Chaque élément traverse l’ensemble du pipeline avant que le suivant ne soit demandé, de sorte que heavyComputation s’exécute uniquement jusqu’à ce que cinq correspondances soient trouvées. Inconvénients : les itérateurs ne peuvent être utilisés qu’une seule fois, il n’y a ni sort ni reverse différés, et pour de petits tableaux, les méthodes immédiates sont tout aussi rapides et plus faciles à déboguer.

Points clés

  • Math.sumPrecise() élimine l’erreur d’arrondi accumulée mais ne peut pas corriger des entrées imprécises ; utilisez des centimes entiers pour les montants monétaires.
  • getOrInsert() remplace has/set/get ; préférez getOrInsertComputed() pour des valeurs par défaut coûteuses.
  • Array.fromAsync() traite séquentiellement les itérables asynchrones ; utilisez Promise.all pour la concurrence.
  • .values() combiné à des outils d’itération permet de créer des pipelines différés similaires à _.chain() sans dépendance externe.