ESx

ES2019

BigInt

BigInt est un nouveau type primitif. Il a la particularité de pouvoir dépassé la limite du type Number. Pour déclarer un nombre en bigint, on pourra la faire de deux manières: 

Number.MAX_SAFE_INTEGER // 9007199254740991 - Limite du type number
const x = BigInt(9007199254740991) // en utilisant l'objet BigInt
const y = 9007199254740991n // ou en précisant un "n" juste après notre nombre
typeof(y) // bigint

En revanche, on ne peut pas faire d'opérations entre deux types différent (entre number et bigint par exemple) mais on peut faire des comparaisons.

const x = 10
const y = 9007199254740991n 
const z = x + y // ❌ Cannot mix BigInt and other types, use explicit conversions

console.log(0n == 0) // ✅ true
console.log(0n === 0) // ❌ false
console.log(2n < 10) // ✅ true

BigInt

BigInt est un nouveau type primitif. Il a la particularité de pouvoir dépassé la limite du type Number. Pour déclarer un nombre en bigint, on pourra la faire de deux manières: 

Number.MAX_SAFE_INTEGER // 9007199254740991 - Limite du type number
const x = BigInt(9007199254740991) // en utilisant l'objet BigInt
const y = 9007199254740991n // ou en précisant un "n" juste après notre nombre
typeof(y) // bigint

En revanche, on ne peut pas faire d'opérations entre deux types différent (entre number et bigint par exemple) mais on peut faire des comparaisons.

const x = 10
const y = 9007199254740991n 
const z = x + y // ❌ Cannot mix BigInt and other types, use explicit conversions

console.log(0n == 0) // ✅ true
console.log(0n === 0) // ❌ false
console.log(2n < 10) // ✅ true

ES2020

BigInt

BigInt est un nouveau type primitif. Il a la particularité de pouvoir dépassé la limite du type Number. Pour déclarer un nombre en bigint, on pourra la faire de deux manières: 

Number.MAX_SAFE_INTEGER // 9007199254740991 - Limite du type number
const x = BigInt(9007199254740991) // en utilisant l'objet BigInt
const y = 9007199254740991n // ou en précisant un "n" juste après notre nombre
typeof(y) // bigint

En revanche, on ne peut pas faire d'opérations entre deux types différent (entre number et bigint par exemple) mais on peut faire des comparaisons.

const x = 10
const y = 9007199254740991n 
const z = x + y // ❌ Cannot mix BigInt and other types, use explicit conversions

console.log(0n == 0) // ✅ true
console.log(0n === 0) // ❌ false
console.log(2n < 10) // ✅ true

Dynamic Import

L'import dynamique permet de différer l'import d'un module au moment où on l'utilise vraiment.

import axios from "axios" // axios est chargé tout de suite peu importe si on l'utilise ou non

button.addEventListener("click", () => {
  axios("https://jsonplaceholder.typicode.com/todos/1")
    .then(response => console.log(response))
})

Avec l'import dynamique, on va faire du lazy-loading et n'importer axios que lorsque le bouton sera effectivement cliqué. Il faut noter qu'un import dynamique renvoie une promise.

button.addEventListener("click", async () => {
  const {default: axios} = await import("axios") // import renvoie une promesse
  const response = await axios("https://jsonplaceholder.typicode.com/todos/1")
  console.log(response.data)
})

Optional Chaining

L'optional chaining permet de régler un problème lorsqu'on doit accéder à des propriétés d'un objet pour pourraient être nulles.

const user = {
  id : 1,
  name : "Jon",
  livesIn : {
    kingdom : {
      name: "Winterfell",
    },
  },
}

if (user && user.livesIn && user.livesIn.kingdom)  // Auparavant 😫
  return user.livesIn.kingdom.name
if (user?.livesIn?.kingdom) // Maintenant - Optional Chaining 🤩
    return user.livesIn.kingdom.name // Maintenant

Les vérifications sont maintenant faites à cotre place, si l'une des valeurs demandée n'existe pas, undefined sera retournée.

Null Coalescing

Le null coalescing est un opérateur qui renvoie son opérande de droite lorsque son opérande de gauche vaut null ou undefined, et qui renvoie son opérande de gauche sinon.

const x1 = null ?? 42 // 42
const x2 = undefined ?? 21 // 21
const x3 = 0 ?? "foo" // 0
const x4 = false ?? "baz" // false

Pour rappel, voici les autres opérateurs logiques:

// ET logique
const x1 = null && 42 // null
const x2 = undefined && 21 // undefined
const x3 = 0 && "foo" // 0
const x4 = false && "bar" // false
const x5 = true && "baz" // baz

// OU logique
const x1 = null || 42 // 42
const x2 = undefined || 21 // 21
const x3 = 0 || "foo" // foo
const x4 = false || "bar" // bar
const x5 = true || "baz" // true

globalThis

globalThis nous permet d'accèder au contexte global quelque soit l'environnement. Ainsi, on peut accéder à l'objet global de façon homogène.

const theGlobalThis = globalThis

Sur nodejs, cela fera référence à global, alors que dans le navigateur, cela fera référence à window.

Promise.allSettled

Cette nouvelle fonctionnalité apporte une nouvelle manière de gérer plusieurs promesses à la fois.

Promise.all prend un tableau de promesses et retourne une promesse si toute sont résolues, mais si une promesse est rejeté, tout le reste est rejeté immédiatement.

Promise.allSettled va renvoyer un tableau avec le résultat de toute les promesses même si une promesse est rejetée.

const resolvedPromise = new Promise((resolve, reject) => setTimeout(resolve('Resolved Promise'), 1000))
const rejectedPromise = new Promise((resolve, reject) => setTimeout(reject(new Error('Rejected Promise')), 2000))

Promise.allSettled([resolvedPromise, rejectedPromise]).then(results => console.log(results))
// [
//   Object { status: "fulfilled", value: "Resolved Promise"},
//   Object { status: "rejected", reason: Error: Rejected Promise}
// ]

String.prototype.matchAll

La méthode matchAll est une version plus précise de la méthode match. Elle renvoie l'index du premier caractère correspondant, la chaine de caractère d'origine, ainsi que le groupe capturant:

const regexp = /t(e)(st(\d?))/g;
const str = 'test1test2';

const array = [...str.matchAll(regexp)];
for (const result of array) {
  console.log(result)
}

/*
  Array ['test1', 'e', 'st1', '1', index: 0, input: 'test1test2', length: 4]
  Array ['test2', 'e', 'st2', '2', index: 5, input: 'test1test2', length: 4]
 */

Module namespace exports

Une nouvelle méthode de faire un export avec un alias dès l'import est maintenant disponible:

// Maintenant
export * as utils from './utils.mjs';

// Auparavant
import * as utils from './utils.mjs';
export { utils };

ESx

By Fabio Ginja

ESx

Slides de formation - ES6 à ES2020

  • 180