17. Nouveautés ECMAScript 2026
ECMAScript 2026 (17ème édition du langage) a été officiellement finalisé par TC39 en 2026. D'après le texte officiel de la spécification (https://tc39.es/ecma262/2026/), cette édition a ajouté : Math.sumPrecise pour additionner un ensemble de nombres en minimisant la perte de précision ; Iterator.concat pour enchaîner des itérateurs ; Array.fromAsync (déjà présenté au chapitre précédent) ; Error.isError pour identifier de façon fiable les objets d'erreur ; des méthodes sur Map.prototype et WeakMap.prototype pour fournir une valeur par défaut lors d'une lecture ; des méthodes sur Uint8Array pour les conversions hexadécimale et base64 ; un paramètre context pour les revivers de JSON.parse ; et JSON.rawJSON pour contrôler finement la sortie de JSON.stringify.
17.1. ⚠️ Un avertissement important, avant de commencer
Le Stage 4 de TC39 garantit que le comportement d'une fonctionnalité ne changera plus, mais ne garantit pas sa disponibilité immédiate dans tous les moteurs JavaScript. En préparant ce chapitre, un fait concret l'a bien montré : [Math.sumPrecise] provoque une erreur TypeError: Math.sumPrecise is not a function, y compris sur des versions récentes de Node.js. Ce n'est pas un bug de ce cours : V8 (le moteur de Node et Chrome) n'a, à ce jour, tout simplement pas encore implémenté cette fonctionnalité — contrairement à Firefox, Safari et Bun, qui l'ont déjà (source : ticket officiel du dépôt TypeScript, github.com/microsoft/TypeScript/issues/63427).
C'est pourquoi chaque script de ce chapitre vérifie lui-même, avec typeof, si la fonctionnalité qu'il illustre est disponible avant de l'utiliser, et affiche un message clair sinon — plutôt que de planter brutalement. C'est une bonne pratique en soi lorsqu'on utilise des fonctionnalités très récentes du langage.
Important : les scripts de ce chapitre ont tous été réellement exécutés dans l'environnement de préparation de ce cours (Node.js 26.7.0) ; certains y affichent le message « non disponible », ce qui est un résultat authentique et non une supposition. Sur votre machine, avec une version de Node.js différente, certains de ces scripts pourront afficher un résultat réel plutôt que ce message — n'hésitez pas à comparer.
17.2. script [01-math-sumPrecise]
| 'use strict';
// ========================================================================
// [NOUVEAU ECMAScript 2026] Math.sumPrecise()
// ========================================================================
// [mise à jour] au moment où ce script est écrit, V8 (donc node et Chrome)
// n'implémente PAS ENCORE Math.sumPrecise, alors que Firefox, Safari et Bun
// l'ont déjà. C'est un exemple concret du décalage qui peut exister entre
// "la fonctionnalité est entrée dans la spécification officielle du langage"
// et "tous les moteurs JavaScript l'ont réellement implémentée" : le Stage 4
// de TC39 (obtenu le 28/07/2025 pour cette fonctionnalité) garantit que le
// comportement ne changera plus, mais ne garantit PAS une disponibilité
// immédiate partout. Voir ecmascript-2026/README.md pour les détails et les
// sources.
// Pour vérifier toi-même si TON node a déjà cette fonctionnalité :
// node -e "console.log(typeof Math.sumPrecise)"
// additionner des nombres flottants avec + accumule des erreurs d'arrondi,
// car chaque nombre est représenté en binaire de façon imprécise
const nombres: number[] = [0.1, 0.2, 0.3, 0.1, 0.2, 0.3, 0.1, 0.2, 0.3, 0.1];
// ------------------------------------------------------------------------
// 1) l'ancienne façon, avec reduce() : le résultat n'est pas exact
// ------------------------------------------------------------------------
const sommeAvecReduce = nombres.reduce((accumulateur, valeur) => accumulateur + valeur, 0);
console.log("somme avec reduce =", sommeAvecReduce);
// on s'attend à 1.9 exactement, mais le résultat contient souvent des décimales parasites
// (ex: 1.9000000000000001) à cause des erreurs d'arrondi qui s'accumulent au fil des additions
// ------------------------------------------------------------------------
// 2) Math.sumPrecise() : additionne tous les nombres de façon exacte
// ------------------------------------------------------------------------
// contrairement à une boucle d'additions successives, l'algorithme utilisé en interne
// évite d'accumuler les erreurs d'arrondi intermédiaires
if (typeof Math.sumPrecise === "function") {
const sommePrécise = Math.sumPrecise(nombres);
console.log("somme avec Math.sumPrecise =", sommePrécise);
} else {
// on évite ici un plantage brutal (TypeError) pour rester pédagogique :
// ce message s'affichera tant que ton moteur JavaScript n'a pas encore
// implémenté cette fonctionnalité pourtant déjà finalisée dans la spec
console.log("Math.sumPrecise n'est pas encore disponible sur ce moteur JavaScript",
"(voir le commentaire en tête de ce fichier)");
}
// ------------------------------------------------------------------------
// pourquoi c'est utile : calculs financiers, comptables, scientifiques -
// partout où une petite erreur d'arrondi répétée peut devenir un vrai bug
// (ex : un total de facture qui ne tombe jamais juste au centime près)
// ------------------------------------------------------------------------
|
npx tsx ecmascript-2026/01-math-sumPrecise.ts
Résultat de l'exécution :
| somme avec reduce = 1.9000000000000004
Math.sumPrecise n'est pas encore disponible sur ce moteur JavaScript (voir le commentaire en tête de ce fichier)
|
17.3. script [02-iterator-concat]
[Iterator.concat] enchaîne plusieurs itérables (tableau, Set, générateur...) en un seul itérateur paresseux (*lazy*) : les éléments ne sont produits qu'au fur et à mesure, sans construire de collection intermédiaire complète — contrairement à l'opérateur de spread [...a, ...b], qui recopie tout immédiatement en mémoire.
| 'use strict';
// ========================================================================
// [NOUVEAU ECMAScript 2026] Iterator.concat()
// ========================================================================
// [Node 26+ - officiellement listé dans les notes de version de node 26.0.0 :
// voir https://nodejs.org/en/blog/release/v26.0.0 - donc normalement déjà
// disponible si tu es sur node 26. Si ce n'est pas le cas, vérifie avec :
// node -e "console.log(typeof Iterator.concat)"
// voir aussi ecmascript-2026/README.md pour le cas des autres nouveautés de
// ce dossier, qui n'ont pas toutes le même niveau de disponibilité]
// on a parfois plusieurs sources de données à parcourir l'une après l'autre
// (par exemple : plusieurs tableaux, ou un tableau puis un Set, ...)
const premièreVague: string[] = ["Ana", "Léo"];
const deuxièmeVague: Set<string> = new Set(["Nora", "Théo"]);
const troisièmeVague: string[] = ["Zoé"];
// ------------------------------------------------------------------------
// 1) l'ancienne façon : il fallait tout regrouper dans un nouveau tableau
// ------------------------------------------------------------------------
const tousLesInvitésTableau: string[] = [...premièreVague, ...deuxièmeVague, ...troisièmeVague];
console.log("avec spread :", tousLesInvitésTableau);
// inconvénient : ceci crée un nouveau tableau EN MÉMOIRE avec tous les éléments recopiés,
// même si on n'a besoin que des 2 premiers (ex: pour un affichage paginé)
// ------------------------------------------------------------------------
// 2) Iterator.concat() : enchaîne les itérables sans les recopier d'abord
// ------------------------------------------------------------------------
// Iterator.concat accepte n'importe quel type d'itérable (tableau, Set, Map, générateur...)
// et rend un itérateur "paresseux" (lazy) : les éléments ne sont produits qu'au fur et à mesure
if (typeof Iterator.concat === "function") {
const tousLesInvités = Iterator.concat(premièreVague, deuxièmeVague, troisièmeVague);
console.log("-----------------------");
for (const invité of tousLesInvités) {
console.log("invité =", invité);
}
// ------------------------------------------------------------------------
// avantage du caractère "paresseux" : on peut s'arrêter en cours de route
// sans avoir payé le coût de construire une collection complète à l'avance
// ------------------------------------------------------------------------
const troisPremiers = Iterator.concat(premièreVague, deuxièmeVague, troisièmeVague)
.take(3)
.toArray();
console.log("trois premiers invités =", troisPremiers);
} else {
console.log("Iterator.concat n'est pas disponible sur ce moteur JavaScript",
"(voir le commentaire en tête de ce fichier)");
}
|
npx tsx ecmascript-2026/02-iterator-concat.ts
Résultat de l'exécution :
| avec spread : [ 'Ana', 'Léo', 'Nora', 'Théo', 'Zoé' ]
-----------------------
invité = Ana
invité = Léo
invité = Nora
invité = Théo
invité = Zoé
trois premiers invités = [ 'Ana', 'Léo', 'Nora' ]
|
17.4. script [03-error-isError]
[Error.isError] détecte de façon fiable si une valeur est une erreur, y compris lorsqu'elle provient d'un autre « royaume » JavaScript (un contexte d'exécution isolé — une iframe, un worker, ou le module vm de node) : chaque royaume a sa propre classe Error, ce qui met instanceof Error en défaut, comme le script le démontre concrètement :
| 'use strict';
// ========================================================================
// [NOUVEAU ECMAScript 2026] Error.isError()
// ========================================================================
// [statut de disponibilité à vérifier toi-même : voir ecmascript-2026/README.md.
// Certaines nouveautés d'ES2026 (comme Math.sumPrecise) sont encore absentes
// de V8 malgré le Stage 4 obtenu - il n'est pas exclu que ce soit aussi le cas
// ici. Vérifie avec : node -e "console.log(typeof Error.isError)"]
// jusqu'ici, pour savoir si une valeur est une erreur, on utilisait [instanceof Error]
// (cf. exceptions/excep-03.ts) - cela fonctionne bien... sauf dans certains cas piégeux
// ------------------------------------------------------------------------
// 1) le piège de [instanceof] avec plusieurs "royaumes" JavaScript
// ------------------------------------------------------------------------
// un "royaume" (realm) est un contexte d'exécution JavaScript isolé : par exemple,
// une iframe dans un navigateur, un worker, ou le module [vm] de node qui permet
// d'exécuter du code dans un contexte séparé. Chaque royaume a SA PROPRE classe [Error],
// distincte de celle du royaume principal.
import vm from 'node:vm';
// on exécute "new Error('venue d'ailleurs')" dans un royaume séparé
const erreurDunAutreRoyaume: unknown = vm.runInNewContext("new Error('venue d\\'ailleurs')");
console.log("erreurDunAutreRoyaume =", erreurDunAutreRoyaume);
// [instanceof Error] échoue ici : ce n'est PAS la même classe [Error] que la nôtre,
// même si l'objet EST bien, conceptuellement, une erreur
console.log("erreurDunAutreRoyaume instanceof Error :", erreurDunAutreRoyaume instanceof Error);
// ------------------------------------------------------------------------
// 2) Error.isError() : détection fiable, même entre royaumes différents
// ------------------------------------------------------------------------
if (typeof Error.isError === "function") {
console.log("Error.isError(erreurDunAutreRoyaume) :", Error.isError(erreurDunAutreRoyaume));
// pour comparaison, sur une erreur "normale" (même royaume), les deux façons de faire
// donnent le même résultat
const erreurNormale = new Error("erreur classique");
console.log("erreurNormale instanceof Error :", erreurNormale instanceof Error);
console.log("Error.isError(erreurNormale) :", Error.isError(erreurNormale));
// et sur une valeur qui n'est clairement pas une erreur
console.log("Error.isError('abc') :", Error.isError("abc"));
console.log("Error.isError(null) :", Error.isError(null));
} else {
console.log("Error.isError n'est pas disponible sur ce moteur JavaScript",
"(voir le commentaire en tête de ce fichier) - mais le piège avec [instanceof]",
"démontré ci-dessus, lui, est bien réel et déjà observable");
}
|
npx tsx ecmascript-2026/03-error-isError.ts
Résultat de l'exécution :
| erreurDunAutreRoyaume = Error: venue d'ailleurs
at evalmachine.<anonymous>:1:1
at Script.runInContext (node:vm:150:12)
at Script.runInNewContext (node:vm:155:17)
at Object.runInNewContext (node:vm:311:38)
at <anonymous> (c:\Data\st-2026\GitHub Pages\fr_FR2\downloads\typescript-sept-2026\ecmascript-2026\03-error-isError.ts:23:43)
at ModuleJob.run (node:internal/modules/esm/module_job:569:25)
at async node:internal/modules/esm/loader:650:26
at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:101:5)
erreurDunAutreRoyaume instanceof Error : false
Error.isError(erreurDunAutreRoyaume) : true
erreurNormale instanceof Error : true
Error.isError(erreurNormale) : true
Error.isError('abc') : false
|
Ce script illustre un point intéressant même sans Error.isError disponible : la ligne erreurDunAutreRoyaume instanceof Error : false montre bien le piège réel que Error.isError est censé résoudre — l'objet est pourtant, conceptuellement, une vraie erreur.
17.5. script [04-map-weakmap-getOrInsert]
[Map.prototype.getOrInsert]/[getOrInsertComputed] répondent à un besoin très fréquent : « si la clé existe déjà, prends sa valeur ; sinon, crée une valeur par défaut et mémorise-la », en une seule ligne plutôt qu'un if (!map.has(clé)) { map.set(...) } verbeux. Le même principe existe pour WeakMap.
| 'use strict';
// ========================================================================
// [NOUVEAU ECMAScript 2026] Map.prototype.getOrInsert / getOrInsertComputed
// ========================================================================
// [Node 26+ - officiellement listé dans les notes de version de node 26.0.0 :
// voir https://nodejs.org/en/blog/release/v26.0.0 - donc normalement déjà
// disponible si tu es sur node 26. Si ce n'est pas le cas, vérifie avec :
// node -e "console.log(typeof Map.prototype.getOrInsert)"
// voir aussi ecmascript-2026/README.md pour le cas des autres nouveautés de
// ce dossier, qui n'ont pas toutes le même niveau de disponibilité]
// un besoin très fréquent : "si la clé existe déjà dans la Map, prends sa valeur ;
// sinon, crée une valeur par défaut, mémorise-la, puis utilise-la"
// ------------------------------------------------------------------------
// 1) l'ancienne façon : if/has() puis set() - verbeux, et facile à mal écrire
// ------------------------------------------------------------------------
const inscriptionsParAtelier = new Map<string, string[]>();
function inscrireAncienneFaçon(atelier: string, participant: string): void {
if (!inscriptionsParAtelier.has(atelier)) {
inscriptionsParAtelier.set(atelier, []);
}
inscriptionsParAtelier.get(atelier)!.push(participant);
// le "!" est nécessaire ici : TypeScript ne peut pas savoir, à cet endroit précis,
// que le .get() qui suit un .set() juste avant réussira forcément
}
inscrireAncienneFaçon("cuisine", "Ana");
inscrireAncienneFaçon("cuisine", "Léo");
console.log("avec l'ancienne façon :", inscriptionsParAtelier);
if (typeof Map.prototype.getOrInsert !== "function") {
console.log("Map.prototype.getOrInsert n'est pas disponible sur ce moteur JavaScript",
"(voir le commentaire en tête de ce fichier) - seule la partie 1) ci-dessus a pu s'exécuter");
} else {
// ------------------------------------------------------------------------
// 2) Map.prototype.getOrInsert() : la même chose, en une seule ligne
// ------------------------------------------------------------------------
const inscriptions2 = new Map<string, string[]>();
const inscrire = (atelier: string, participant: string): void => {
// rend le tableau existant pour [atelier], ou l'initialise à [] s'il n'existe pas encore
inscriptions2.getOrInsert(atelier, []).push(participant);
}
inscrire("poterie", "Nora");
inscrire("poterie", "Théo");
console.log("avec getOrInsert :", inscriptions2);
// ------------------------------------------------------------------------
// 3) getOrInsertComputed() : la valeur par défaut n'est calculée QUE si besoin
// ------------------------------------------------------------------------
// avec getOrInsert(clé, valeur), la [valeur] par défaut est TOUJOURS évaluée,
// même quand la clé existe déjà et qu'on n'en a pas besoin (ici ce n'est pas
// grave pour un tableau vide [], mais ça peut l'être pour un calcul coûteux)
const compteurs = new Map<string, number>();
const incrémenter = (clé: string): void => {
// le callback n'est appelé QUE si la clé n'existe pas encore dans la Map
const valeur = compteurs.getOrInsertComputed(clé, () => {
console.log(`[calcul de la valeur initiale pour "${clé}"]`);
return 0;
});
compteurs.set(clé, valeur + 1);
}
incrémenter("visites");
incrémenter("visites"); // ici, le callback ne sera PAS réexécuté
incrémenter("clics");
console.log("compteurs =", compteurs);
// ------------------------------------------------------------------------
// 4) WeakMap.prototype.getOrInsert / getOrInsertComputed : même principe,
// pour associer des données supplémentaires à des objets sans empêcher leur
// nettoyage par le ramasse-miettes (garbage collector)
// ------------------------------------------------------------------------
interface Métadonnées {
vues: number;
}
const métadonnéesParObjet = new WeakMap<object, Métadonnées>();
const enregistrerUneVue = (objet: object): void => {
const métadonnées = métadonnéesParObjet.getOrInsertComputed(objet, () => ({ vues: 0 }));
métadonnées.vues++;
}
const article = { titre: "Découverte du WeakMap" };
enregistrerUneVue(article);
enregistrerUneVue(article);
console.log("métadonnées de l'article =", métadonnéesParObjet.get(article));
}
|
npx tsx ecmascript-2026/04-map-weakmap-getOrInsert.ts
Résultat de l'exécution :
| avec l'ancienne façon : Map(1) { 'cuisine' => [ 'Ana', 'Léo' ] }
avec getOrInsert : Map(1) { 'poterie' => [ 'Nora', 'Théo' ] }
[calcul de la valeur initiale pour "visites"]
[calcul de la valeur initiale pour "clics"]
compteurs = Map(2) { 'visites' => 2, 'clics' => 1 }
métadonnées de l'article = { vues: 2 }
|
17.6. script [05-uint8array-base64-hex]
Uint8Array (un tableau typé d'octets bruts) reçoit de nouvelles méthodes de conversion vers/depuis le base64 et l'hexadécimal — des formats couramment utilisés pour transmettre des données binaires en JSON ou en URL, sans dépendre d'un package tiers :
| 'use strict';
// ========================================================================
// [NOUVEAU ECMAScript 2026] Uint8Array : conversion base64 et hexadécimal
// ========================================================================
// [statut de disponibilité à vérifier toi-même : voir ecmascript-2026/README.md.
// Certaines nouveautés d'ES2026 (comme Math.sumPrecise) sont encore absentes
// de V8 malgré le Stage 4 obtenu - il n'est pas exclu que ce soit aussi le cas
// ici. Vérifie avec : node -e "console.log(typeof Uint8Array.prototype.toBase64)"]
// [Uint8Array] est un tableau typé qui stocke des octets bruts (valeurs 0-255) -
// par exemple le contenu d'un fichier, une image, ou une donnée reçue par le réseau
// avant 2026, pour encoder ces octets en base64 (le format utilisé par exemple
// dans les URLs de données "data:", ou pour transmettre du binaire en JSON),
// il fallait passer par des fonctions détournées ou des packages tiers (buffer côté node,
// btoa/atob côté navigateur - imparfaits et pas conçus pour ça à l'origine)
const octets = new Uint8Array([72, 101, 108, 108, 111]); // "Hello" en codes ASCII
if (typeof octets.toBase64 !== "function") {
console.log("Uint8Array.prototype.toBase64 n'est pas disponible sur ce moteur JavaScript",
"(voir le commentaire en tête de ce fichier)");
} else {
// ------------------------------------------------------------------------
// 1) encodage en base64
// ------------------------------------------------------------------------
const enBase64 = octets.toBase64();
console.log("octets en base64 =", enBase64);
// décodage : reconstruire un Uint8Array à partir d'une chaîne base64
const octetsRetrouvés = Uint8Array.fromBase64(enBase64);
console.log("octets retrouvés =", octetsRetrouvés);
console.log("identiques à l'original :", octets.toString() === octetsRetrouvés.toString());
// ------------------------------------------------------------------------
// 2) encodage en hexadécimal
// ------------------------------------------------------------------------
const enHexadécimal = octets.toHex();
console.log("octets en hexadécimal =", enHexadécimal);
const octetsDepuisHex = Uint8Array.fromHex(enHexadécimal);
console.log("octets depuis hex =", octetsDepuisHex);
// ------------------------------------------------------------------------
// 3) remplir un Uint8Array existant, à partir d'un offset donné
// ------------------------------------------------------------------------
// utile pour assembler plusieurs morceaux dans un même buffer, sans allocations
// intermédiaires
const buffer = new Uint8Array(10);
const résultatEcriture = buffer.setFromHex("48656c6c6f"); // "Hello" en hexadécimal
console.log("buffer après setFromHex =", buffer);
console.log("caractères lus / écrits =", résultatEcriture);
}
// ------------------------------------------------------------------------
// pourquoi c'est utile : transmission de données binaires dans des formats texte
// (JSON, URL, headers HTTP...), sans dépendre d'un package tiers ou de bricolages
// ------------------------------------------------------------------------
|
npx tsx ecmascript-2026/05-uint8array-base64-hex.ts
Résultat de l'exécution :
| octets en base64 = SGVsbG8=
octets retrouvés = Uint8Array(5) [ 72, 101, 108, 108, 111 ]
identiques à l'original : true
octets en hexadécimal = 48656c6c6f
octets depuis hex = Uint8Array(5) [ 72, 101, 108, 108, 111 ]
buffer après setFromHex = Uint8Array(10) [
72, 101, 108, 108, 111,
0, 0, 0, 0, 0
]
caractères lus / écrits = { read: 10, written: 5 }
|
17.7. script [06-json-rawJSON-et-reviver]
Ce dernier script se distingue des précédents : [JSON.rawJSON]/[isRawJSON], ainsi que le nouveau paramètre context du reviver de JSON.parse, fonctionnent déjà dans l'environnement de préparation de ce cours (Node 22) :
| 'use strict';
// ========================================================================
// [NOUVEAU ECMAScript 2026] JSON.rawJSON / JSON.isRawJSON, et le contexte du reviver
// ========================================================================
// [ces deux nouveautés fonctionnent déjà avec node 22, contrairement aux autres
// scripts de ce dossier qui nécessitent node 24 - voir ecmascript-2026/README.md]
// ------------------------------------------------------------------------
// 1) le problème : JSON.stringify perd de la précision sur les grands entiers
// ------------------------------------------------------------------------
// un nombre JavaScript classique (type [number]) ne peut pas représenter
// exactement les entiers au-delà de Number.MAX_SAFE_INTEGER (cf. bases/bases-09.ts)
// beaucoup d'API (bases de données, réseaux sociaux, ...) envoient pourtant des
// identifiants numériques à 17-19 chiffres dans leur JSON
const identifiantColonneBaseDeDonnées = "9007199254740993123"; // trop grand pour un [number]
interface Enregistrement {
id: unknown; // unknown ici car ce sera soit un RawJSON, soit une valeur normale
nom: string;
}
// ------------------------------------------------------------------------
// 2) JSON.rawJSON() : insère un nombre "brut" dans un JSON.stringify,
// sans jamais le faire passer par le type [number] (donc sans perte de précision)
// ------------------------------------------------------------------------
const enregistrement: Enregistrement = {
id: JSON.rawJSON(identifiantColonneBaseDeDonnées),
nom: "capteur-température-3"
};
const texteJSON = JSON.stringify(enregistrement);
console.log("texteJSON =", texteJSON);
// l'identifiant apparaît tel quel dans le texte produit, chiffre pour chiffre,
// alors qu'un id: Number(identifiantColonneBaseDeDonnées) aurait été arrondi
// JSON.isRawJSON() permet de vérifier si une valeur a été créée par JSON.rawJSON
console.log("JSON.isRawJSON(enregistrement.id) =", JSON.isRawJSON(enregistrement.id));
// ------------------------------------------------------------------------
// 3) le reviver de JSON.parse reçoit maintenant un 3ième paramètre [context]
// ------------------------------------------------------------------------
// avant 2026, le reviver ne recevait que (clé, valeur) : impossible de savoir
// quel était le texte JSON EXACT d'où venait cette valeur (utile justement
// pour récupérer un grand nombre sans perte, en le gardant sous forme de texte)
const objetRelu = JSON.parse(texteJSON, (clé, valeur, context) => {
// [context.source] donne le texte JSON brut correspondant à cette valeur,
// avant toute conversion en type JavaScript - undefined pour les objets/tableaux
if (context?.source !== undefined) {
console.log(`clé="${clé}", valeur convertie=${valeur}, texte JSON d'origine="${context.source}"`);
}
return valeur;
});
console.log("objetRelu =", objetRelu);
|
- [JSON.rawJSON(texte)] insère un nombre « brut » dans JSON.stringify, sans jamais le faire passer par le type number — utile pour les très grands identifiants numériques (au-delà de Number.MAX_SAFE_INTEGER, voir bases-09), qui perdraient sinon en précision ;
- le 3ᵉ paramètre context du reviver donne accès, via context.source, au texte JSON brut de la valeur en cours de traitement — avant toute conversion en type JavaScript.
npx tsx ecmascript-2026/06-json-rawJSON-et-reviver.ts
Résultat de l'exécution :
| texteJSON = {"id":9007199254740993123,"nom":"capteur-température-3"}
JSON.isRawJSON(enregistrement.id) = true
clé="id", valeur convertie=9007199254740993000, texte JSON d'origine="9007199254740993123"
clé="nom", valeur convertie=capteur-température-3, texte JSON d'origine=""capteur-température-3""
objetRelu = { id: 9007199254740993000, nom: 'capteur-température-3' }
|
On observe très concrètement l'intérêt de JSON.rawJSON : le texte JSON produit conserve l'identifiant chiffre pour chiffre (9007199254740993123), alors qu'un simple id: Number(...) l'aurait arrondi — comme le montre justement la valeur relue par JSON.parse (9007199254740993000), qui, elle, est bien passée par le type number et a perdu en précision.