Innovations ES2020 que j'aime beaucoup

JavaScript s'est développé très rapidement ces dernières années. Cela est particulièrement vrai pour la période suivant la publication de la norme ES6 en 2015. Depuis lors, de nombreuses fonctionnalités intéressantes sont apparues dans la langue. De nombreuses nouveautés ont été proposées pour inclusion dans la norme ES2020. Une liste finale de fonctionnalités a déjà été établie, dont l'apparence peut être attendue dans la norme après son approbation. C'est une bonne nouvelle pour tous les passionnés de JS. L'auteur de l'article, dont nous publions aujourd'hui la traduction, dit que parmi ces opportunités il y en a qui lui plaisent particulièrement. Avant leur apparition, il lui était beaucoup plus difficile d'écrire du code dans les situations où elles étaient applicables. Selon lui, s'ils étaient apparus dans la langue plus tôt, ils lui auraient fait gagner beaucoup de temps et d'efforts.





Chaînes en option


Le chaînage en option est, pour moi personnellement, l'une des caractéristiques les plus intéressantes de la norme ES2020. J'ai écrit de nombreux programmes dans lesquels cette fonctionnalité serait extrêmement utile. 

Les chaînes en option vous permettent d'organiser un accès sécurisé aux propriétés profondément intégrées des objets sans avoir besoin de vérifier l'existence de chacun d'entre eux. Jetez un œil au fonctionnement de cette fonctionnalité.

Tout d'abord, regardez le code qui devait être écrit avant l'avènement des chaînes optionnelles.

▍ Code avant l'apparition des chaînes optionnelles


const user = {
   firstName:"Joseph",
   lastName:"Kuruvilla",
   age:38,
   address:{
      number:"239",
      street:"Ludwig Lane",
      city:"Chennai",
      zip:"600028",
   prop1:{
    prop2:{
     prop3:{
      prop4:{
       value:'sample'
      }
     }
    }
   }
   }
}
if(user && user.address){
 console.log(user.address.zip);
 //600028
}
if(user && user.address && user.address.prop1 && user.address.prop1.prop2 && user.address.prop1.prop2.prop3 && user.address.prop1.prop2.prop3.prop4){
 console.log(user.address.prop1.prop2.prop3.prop4.value);
 //sample
}
//    
console.log(user.address.prop102.po);
//Error

Comme vous pouvez le voir, pour éviter l'apparition d'erreurs, il semble Cannot read property 'po' of undefinedqu'il soit nécessaire, à chaque niveau d'imbrication, de vérifier les propriétés de leur existence. Avec une augmentation de la profondeur d'imbrication des entités, le nombre de propriétés vérifiées augmente également. Cela signifie que le programmeur lui-même doit écrire du code qui le protège des propriétés qui, une fois accédées, peuvent s'exécuter dans les valeurs de nullou undefined.

▍ Code après l'apparition de chaînes optionnelles


L'écriture de code comme celui que nous venons de réviser a rendu les choses beaucoup plus faciles avec l'avènement des chaînes optionnelles. Pour organiser un travail sûr avec des propriétés d'objets profondément intégrées, il suffit d'utiliser l'opérateur ?.. Cela nous évite d'avoir à vérifier indépendamment les valeurs sur nullet undefined.

Voici à quoi ça ressemble:

const user = {
   firstName:"Joseph",
   lastName:"Kuruvilla",
   age:38,
   address:{
      number:"239",
      street:"Ludwig Lane",
      city:"Chennai",
      zip:"600028",
   prop1:{
    prop2:{
     prop3:{
      prop4:{
       value:'sample'
      }
     }
    }
   }
   }
}
console.log(user?.address?.zip);
//600028
console.log(user?.address?.prop1?.prop2?.prop3?.prop4?.value);
//sample
//    
console.log(user?.address?.prop102?.po);
//undefined

Eh bien, ça ne va pas? Grâce à cette innovation, ES2020 a permis de se débarrasser d'un grand nombre de lignes de code.

Validation uniquement des valeurs nulles et non définies


La vérification des valeurs uniquement sur nullet undefined(coalescence nulle) est l'une de ces fonctionnalités qui m'a vraiment ravi même lorsque les possibilités étaient au stade de la proposition. J'ai souvent rencontré le besoin d'écrire des fonctions spécialisées pour effectuer les vérifications appropriées.

JavaScript est connu pour avoir des significations «fausses» et «vraies». Nous pouvons maintenant dire que des valeurs «zéro» leur ont été ajoutées. Ces valeurs incluent nullet undefined. Avec des termes de JavaScript « false » sont des chaînes vides, le nombre 0, les valeurs undefined, null, false, NaN. C'est-à-dire, par exemple, une certaine expression pour vérifier la valeur de «falsehood» fonctionnera sur une chaîne vide et sur la valeurundefined, et bien plus encore sur quoi. Et l'expression de vérification de la valeur de «zéro» ne renvoie trueque pour nullet undefined. Peut-être que cette opportunité ne vous semble pas si merveilleuse personnellement, mais, en fait, elle est très, très importante.

Regardons quelques exemples.

▍ Le code jusqu'à la possibilité de vérifier les valeurs uniquement sur null et indéfini


Récemment, je travaillais sur un projet dans lequel j'avais besoin de mettre en œuvre la fonctionnalité de commutation entre les thèmes clairs et sombres. Dans le même temps, j'ai dû vérifier l'état du contrôle, savoir s'il correspond à la valeur de trueou false. Si l'utilisateur n'a défini aucune valeur, par défaut, elle doit être égale true. Voici comment j'ai résolu ce problème avant la possibilité de vérifier les valeurs uniquement sur nullet undefined:

const darkModePreference1 = true
const darkModePreference2 = false
const darkModePreference3 = undefined
const darkModePreference4 = null
const getUserDarkModePreference = (darkModePreference) => {
  if (darkModePreference || darkModePreference === false) {
    return darkModePreference
  }
  return true
}
getUserDarkModePreference(darkModePreference1) 
// true
getUserDarkModePreference(darkModePreference2) 
// false
getUserDarkModePreference(darkModePreference3) 
// true
getUserDarkModePreference(darkModePreference4) 
// true

▍ Code après la possibilité de vérifier les valeurs uniquement sur null et indéfini


Une fois que cette fonctionnalité est apparue dans la langue de vérification nullet undefinedd'opérateur suffisante ??. Dans ce cas, vous pouvez vous passer d'un opérateur conditionnel if:

const darkModePreference1 = true
const darkModePreference2 = false
const darkModePreference3 = undefined
const darkModePreference4 = null
const getUserDarkModePreference = (darkModePreference) => {
  return darkModePreference ?? true;
}
getUserDarkModePreference(darkModePreference1) 
// true
getUserDarkModePreference(darkModePreference2) 
// false
getUserDarkModePreference(darkModePreference3) 
// true
getUserDarkModePreference(darkModePreference4) 
// true

Voici ce qui se produit: si la variable darkModePreferencecontient une valeur "zéro", alors la valeur est retournée true. Cela facilite l'écriture de code, il est compact et facile à comprendre.

Importations dynamiques


Les importations dynamiques contribuent à des performances d'application plus efficaces. Cette technologie vous permet d'importer des fichiers JS dynamiquement, sous forme de modules, sans impliquer d'outils supplémentaires. De plus, si le module n'est pas nécessaire, il n'est pas importé. Avant l'ES2020, les modules étaient importés, qu'ils soient utilisés par l'application ou non.

Par exemple, supposons que nous devons implémenter la fonctionnalité de chargement d'un certain fichier au format PDF.

Considérez, comme d'habitude, les anciennes et les nouvelles options pour résoudre ce problème.

▍ Code avant la prise en charge des importations dynamiques


Sur la base de la situation réelle, nous pouvons nous attendre à ce que la possibilité de télécharger des documents au format PDF ne soit pas utilisée par tous les visiteurs de la page. Mais le module correspondant, de toute façon, doit être importé dans le code. Cela signifie que le module, qu'il soit nécessaire ou non, sera chargé lors du chargement de la page.

import { exportAsPdf } from './export-as-pdf.js'
const exportPdfButton = document.querySelector('.exportPdfBtn');
exportPdfButton.addEventListener('click', exportAsPdf);

Cela crée une charge supplémentaire sur le système, qui peut être facilitée en utilisant le chargement paresseux des modules. Cela peut être fait en utilisant la technologie de séparation de code, qui est disponible dans le webpack ou dans d'autres chargeurs de modules (et leur utilisation en soi signifie dépenser une certaine quantité de ressources système).

Mais maintenant, grâce à l'ES2020, nous avons un moyen standard de charger dynamiquement les modules, ce qui nous permet de nous passer de bundles.

▍ Code après l'apparition du support des importations dynamiques


const exportPdfButton = document.querySelector('.exportPdfBtn');
exportPdfButton.addEventListener('click', () => {
  import('./export-as-pdf.js')
    .then(module => {
      module.exportAsPdf()
    })
    .catch(err => {
      //      -  
    })
})

Comme vous pouvez le voir, vous pouvez désormais organiser le chargement paresseux des modules en chargeant uniquement lorsque le module approprié est nécessaire. Cela réduit la charge du système et augmente la vitesse de chargement des pages.

Construct Promise.allSettled


Si vous devez effectuer une action uniquement si toutes les promesses ont été résolues avec succès, vous pouvez utiliser la méthode Promise.all(). Certes, cette méthode a un inconvénient. La méthode générera une erreur si au moins une promesse qui lui est passée est rejetée. Cela signifie que l'action nécessaire ne sera pas effectuée tant que toutes les promesses n'auront pas été résolues.

Vous n'en aurez peut-être pas besoin. Peut-être que le scénario suivant vous conviendra: «Le résultat n'est pas important pour moi. J'ai besoin que le code soit exécuté après la fin de toutes les promesses. » Dans ce cas, la méthode vous est utile Promise.allSettled(). La promesse correspondante n'est résolue avec succès qu'après la fin des autres promesses. Peu importe qu'ils aient réussi ou échoué.

▍ Code utilisant la construction Promise.all


const PromiseArray = [
    Promise.resolve(100),
    Promise.reject(null),
    Promise.resolve("Data release"),
    Promise.reject(new Error('Something went wrong'))];
Promise.all(PromiseArray)
  .then(data => console.log('all resolved! here are the resolve values:', data))
  .catch(err => console.log('got rejected! reason:', err))
//got rejected! reason: null

Apparemment, il Promise.alldonne une erreur après le rejet d'une des promesses qui lui ont été transférées.

▍ Code qui utilise la construction Promise.allSettled


const PromiseArray = [
    Promise.resolve(100),
    Promise.reject(null),
    Promise.resolve("Data release"),
    Promise.reject(new Error('Something went wrong'))];
Promise.allSettled(PromiseArray).then(res =>{
console.log(res);
}).catch(err => console.log(err));
//[
//{status: "fulfilled", value: 100},
//{status: "rejected", reason: null},
//{status: "fulfilled", value: "Data release"},
//{status: "rejected", reason: Error: Something went wrong ...}
//]

Et ici, bien que certaines des promesses soient rejetées, il Promise.allSettledrenvoie les résultats émis par toutes les promesses qui lui ont été transférées.

Autres caractéristiques notables


▍ Type de données BigInt


Le nouveau type de données BigIntvous permet de travailler avec des nombres dont la longueur dépasse la longueur des nombres avec lesquels vous pouvez travailler en JavaScript avant qu'il n'apparaisse ( pow(2,53)-1). Certes, ce type de données n'est pas rétrocompatible avec ce qui était auparavant dans la langue. La norme IEEE 754, qui est la base de l'utilisation des nombres en JavaScript, ne prend pas en charge les nombres avec lesquels il est possible de travailler.BigInt

▍ Méthode String.prototype.matchAll


La méthode String.prototype.matchAll()est liée aux expressions régulières. Il renvoie un itérateur, vous permettant de travailler avec toutes les correspondances trouvées dans une chaîne à l'aide d'une expression régulière , y compris les groupes .

▍ Global property globalThis


La propriété globale globalThiscontient une référence à l'objet global correspondant à l'environnement dans lequel le code est exécuté. Dans le navigateur, l'objet global est représenté par l'objet window. Dans Node.js, il s'agit d'un objet global. Chez les travailleurs du Web, c'est un objet self.

Quelles innovations aimez-vous le plus dans l'ES2020?


All Articles