Publié par

Il y a 3 semaines -

Temps de lecture 5 minutes

Pépite #19 – Introduction du nullish coalescing dans ECMAScript

ECMAScript est un standard évoluant en permanence et de nouvelles normes font régulièrement leur apparition. C’est le cas de ces deux nouvelles propositions (parmi d’autres) faisant particulièrement parler d’elles dans le monde JavaScript : Le nullish coalescing et l’optional chaining !

En effet, le tc39 (Technical Committee 39), le comité chargé de définir les nouveaux standards d’ECMAScript, a validé ces deux fonctionnalités et les a placées au niveau 3 de validation (stage 3), cela indique que ces propositions sont suffisamment matures pour être prises en considération. Le comité attend maintenant le feedback des utilisateurs et les implémentations qui satisferont leurs critères d’acceptances.

Nous allons voir un peu plus en détail, ce que le nullish coalescing peut nous apporter. Si vous êtes intéréssé(e) par l’optional chaining, je vous invite à vous rendre sur cet article qui lui est dédié : Pépite #21 – ECMAScript va introduire l’optional chaining dans sa norme.

Qu’est ce que le nullish coalescing ?

C’est un nouvel opérateur ?? qui se rapproche de l’opérateur OU || a la différence près que ce dernier vérifie qu’une valeur est truthy. Quant au nullish coalescing, il vérifie le fait qu’une variable ou un attribut soit défini. C’est-à-dire qu’il a été déclaré et contient une valeur autre que null ou undefined.

Par exemple :

const result = null ?? "default"; 
// result = "default";

On serait tenté de dire que l’on ne voit pas spécialement la différence avec l’opérateur ||, avec lequel on pourrait faire exactement la même chose.

Le souci, dans cette approche, est que beaucoup trop de valeurs peuvent être considérées comme falsy lorsque nous voulons vérifier l’existence d’une variable.
Pour rappel, voici une liste des éléments qui sont considérés comme falsy et qui, de fait, renverront false lors de l’évaluation d’une condition :

if (false) 
if (null) 
if (undefined) 
if (0) 
if (NaN) 
if ('') 
if ("") 
if (document.all)

(exemple issu du Mozilla Developer Network )

Dans les exemples ci-dessus les évaluations seront toujours false, de ce fait si nous reprenons une de ces valeurs pour l’appliquer dans une instruction contenant l’opérateur ||, la valeur retournée sera toujours celle à droite de l’opérateur. Si on prend l’exemple suivant :

const result = 0 || 'default'; 

Le résultat de cette instruction sera toujours default.

Cette tolérance dans la validation des valeurs peut amener à avoir des comportements non désirés.
Voici quelques exemples issus de la proposition fournie pour le tc39. Supposons le code suivant :

const response = {
	settings: { 
		nullValue: null, 
		height: 400, 
		animationDuration: 0, 
		headerText: '', 
		showSplashScreen: false 
	} 
}; 
const undefinedValue = response.settings.undefinedValue || 'some other default'; 
// result: 'some other default' 
const nullValue = response.settings.nullValue || 'some other default'; 
// result: 'some other default' 
const headerText = response.settings.headerText || 'Hello, world!';
// Potentially unintended. '' is falsy, result: 'Hello, world!' 
const animationDuration = response.settings.animationDuration || 300; 
// Potentially unintended. 0 is falsy, result: 300 
const showSplashScreen = response.settings.showSplashScreen || true; 
// Potentially unintended. false is falsy, result: true

Il est donc impossible de faire une validation simple pour les chaines de caractères, les nombres et les booléens sans risquer d’introduire un bug dont la cause pourrait être difficile à retrouver.
Jusqu’ici, nous nous reposions sur des méthodes de contournement afin d’éviter cet écueil. Par exemple en utilisant plusieurs if ou en se reposant sur des bibliothèques externes, ce qui peut alourdir la lisibilité du code.

Dans le cas suivant, si nous voulons vérifier que l’attribut showSplashScreen est présent sans risquer de remplacer une potentielle valeur définie sur false, nous n’avons pas d’autre choix que de changer de syntaxe et nous nous retrouvons assez rapidement avec ce genre de vérification :

let showSplashScreen = response.settings.showSplashScreen
if(showSplashScreen === null || showSplashScreen === undefined) {
  showSplashScreen = true;
}

C’est dans cette optique que l’opérateur ?? a été proposé. Il permet de pallier ce genre de problème et d’obtenir un comportement plus précis.

Le code ci-dessus peut être modifié en utilisant le nullish coalescing :

const response = {
	settings: { 
		nullValue: null, 
		height: 400, 
		animationDuration: 0, 
		headerText: '', 
		showSplashScreen: false 
	} 
}; 

const undefinedValue = response.settings.undefinedValue ?? 'some other default'; 
// result: 'some other default' 
const nullValue = response.settings.nullValue ?? 'some other default'; 
// result: 'some other default' 
const headerText = response.settings.headerText ?? 'Hello, world!'; 
// result: '' 
const animationDuration = response.settings.animationDuration ?? 300; 
// result: 0 
const showSplashScreen = response.settings.showSplashScreen ?? true; 
// result: false

Tout porte à croire que cela va grandement simplifier la vie de beaucoup de personnes travaillant avec JavaScript, notamment celles et ceux devant gérer des API qui nécessitent une validation des données en entrée.

Quand pourra-t-on les utiliser ?

Actuellement ces deux fonctionnalités sont au stage 3 de publication pour le tc39, nous pouvons donc espérer que cette nouvelle syntaxe sera intégrée dans la prochaine version d’ECMAScript d’ici le mois de juillet 2020 (le comité se réunissant tous les ans à cette période afin de valider les nouvelles normes).

Une implémentation sous forme de patch a déjà été créée pour Webkit. TypeScript l’implémentera dans sa prochaine version 3.7 (accessible uniquement en bêta pour le moment).

En attendant une implémentation officielle, il est d’ores et déjà possible de simuler ce comportement en utilisant le plugin babel dédié au nullish coalescing.

Il est possible de suivre l’avancée des travaux via le GitHub dédié au TC39.

Publié par

Commentaire

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Nous recrutons

Être un Xebian, c'est faire partie d'un groupe de passionnés ; C'est l'opportunité de travailler et de partager avec des pairs parmi les plus talentueux.