From 93ca3cca54f08f30aa057f4f835140773b13008c Mon Sep 17 00:00:00 2001 From: Vincent Clipet Date: Mon, 10 Mar 2025 16:29:24 +0100 Subject: [PATCH] fix: Deleted a useless file in project root The project root folder contains a file named '=' which seems to be an old copy of the '1-js\04-object-basics\07-optional-chaining' file which was most likely created by mistake 5 years ago --- = | 237 -------------------------------------------------------------- 1 file changed, 237 deletions(-) delete mode 100644 = diff --git a/= b/= deleted file mode 100644 index a13475b5a..000000000 --- a/= +++ /dev/null @@ -1,237 +0,0 @@ - - -# Chaînage optionnel '?.' - -[recent browser="new"] - - -Le chaînage optionnel `?.` Est un moyen sécurisé d'accéder aux propriétés d'objet imbriquées, même si une propriété intermédiaire n'existe pas. - -## Le problème de la "propriété non existante" - - -Si vous venez de commencer à lire le tutoriel et à apprendre JavaScript, peut-être que le problème ne vous a pas encore touché, mais c'est assez courant. - - -À titre d'exemple, disons que nous avons des objets `user` qui contiennent les informations sur nos utilisateurs. - -La plupart de nos utilisateurs ont des adresses dans la propriété `user.address`, avec la rue `user.address.street`, mais certains ne les ont pas fournies. - -Dans ce cas, lorsque nous essayons d'obtenir `user.address.street`, et que l'utilisateur se trouve sans adresse, nous obtenons une erreur : - -```js run -let user = {}; // un utilisateur sans propriété "address" - - -alert(user.address.street); // Error! -``` - -C'est le résultat attendu. JavaScript fonctionne comme ça. Comme `user.address` est `undefined`, une tentative d'obtention de `user.address.street` échoue avec une erreur. - -Dans de nombreux cas pratiques, nous préférerions obtenir `undefined` au lieu d'une erreur ici (signifiant "pas de rue"). - -... Et un autre exemple. Dans le développement Web, nous pouvons obtenir un objet qui correspond à un élément de page Web à l'aide d'un appel de méthode spécial, tel que `document.querySelector('.elem')`, et il renvoie `null` lorsqu'il n'y a pas ce type d'élément. - -```js run -// document.querySelector('.elem') est nul s'il n'y a pas d'élément -let html = document.querySelector('.elem').innerHTML; // error if it's null -``` - -Encore une fois, si l'élément n'existe pas, nous obtiendrons une erreur lors de l'accès à `.innerHTML` de `null`. Et dans certains cas, lorsque l'absence de l'élément est normale, nous aimerions éviter l'erreur et accepter simplement `html = null` comme résultat. - -Comment peut-on le faire ? - -La solution évidente serait de vérifier la valeur en utilisant `if` ou l'opérateur conditionnel `?`, Avant d'accéder à sa propriété, comme ceci : - -```js -let user = {}; - -alert(user.address ? user.address.street : undefined); -``` - -Cela fonctionne, il n'y a pas d'erreur ... Mais c'est assez inélégant. Comme vous pouvez le voir, `"user.address"` apparaît deux fois dans le code. Pour des propriétés plus profondément imbriquées, cela devient un problème car plus de répétitions sont nécessaires. - -Par exemple. essayons d'obtenir `user.address.street.name`. - -Nous devons vérifier à la fois `user.address` et `user.address.street` : - -```js -let user = {}; // l'utilisateur n'a pas d'adresse - -alert(user.address ? user.address.street ? user.address.street.name : null : null); -``` - -C'est juste horrible, on peut même avoir des problèmes pour comprendre un tel code. - -Ne vous en souciez même pas, car il existe une meilleure façon de l'écrire, en utilisant l'opérateur `&&` : - -```js run -let user = {}; // l'utilisateur n'a pas d'adresse - -alert( user.address && user.address.street && user.address.street.name ); // undefined (no error) -``` - -Et le chemin complet vers la propriété garantit que tous les composants existent (sinon, l'évaluation s'arrête), mais n'est pas non plus idéal. - -Comme vous pouvez le voir, les noms de propriétés sont toujours dupliqués dans le code. Par exemple. dans le code ci-dessus, `user.address` apparaît trois fois. - -C'est pourquoi le chaînage facultatif `?.` A été ajouté au langage. Pour résoudre ce problème une fois pour toutes ! - -ET l'ensemble du chemin d'accès à la propriété garantit que tous les composants existent (sinon, l'évaluation s'arrête), mais est difficile à écrire. - - -## Chaînage optionnel - -Le chaînage facultatif `?.` arrête l'évaluation et renvoie `undefined` si la partie avant `?.` est `undefined` ou `null` et renvoie cette partie. - -**Plus loin dans cet article, par souci de brièveté, nous dirons que quelque chose "existe" si ce n'est pas "null" et non "undefined".** - -En d'autres termes, `value?.prop` : -- est identique à `value.prop` si `value` existe, -- sinon (lorsque `value` est `undefined/nul`), il renvoie `undefined`. - -Voici le moyen sûr d'accéder à `user.address.street` en utilisant `?.` : - -```js run -let user = {}; // l'utilisateur n'a pas d'adresse - -alert( user?.address?.street ); // undefined (no error) -``` - -Le code est court et propre, il n'y a aucune duplication. - -La lecture de l'adresse avec `user?.address` fonctionne même si l'objet `user` n'existe pas : - -```js run -let user = null; - -alert( user?.address ); // undefined -alert( user?.address.street ); // undefined -``` - -Remarque: la syntaxe `?.` Rend facultative la valeur qui la précède, mais pas plus. - -Par exemple. dans `user?.address.street.name` le `?.` permet à `user` d'être `null/undefined`, mais c'est tout ce qu'il fait. D'autres propriétés sont accessibles de manière régulière. Si nous voulons que certains d'entre eux soient optionnels, alors nous devrons remplacer plus de `.` par `?.`. - -```warn header="N'abusez pas du chaînage optionnel" -Nous ne devrions utiliser `?.` que là où il est normal que quelque chose n'existe pas. - -Par exemple, si selon notre logique de codage, l'objet `user` doit exister, mais que `address` est facultatif, alors nous devrions écrire `user.address?.street`, mais pas `user?.address?.street`. - -``` - -````warn header="La variable avant `?.` doit être déclarée" -S'il n'y a pas du tout de variable `user`, alors `user?.anything` déclenche une erreur : - -```js run -// ReferenceError: user is not defined -user?.address; -``` -La variable doit être déclarée (par exemple `let/const/var user` ou en tant que paramètre de fonction). Le chaînage facultatif ne fonctionne que pour les variables déclarées. -```` - -## Court-circuit - -Comme il a été dit précédemment, le `?.` arrête immédiatement ("court-circuite") l'évaluation si la partie gauche n'existe pas. - - -Donc, s'il y a d'autres appels de fonction ou effets secondaires, ils ne se produisent pas : - -Par exemple : - -```js run -let user = null; -let x = 0; - - -user?.sayHi(x++); // pas de "sayHi", donc l'exécution n'atteint pas x++ - - -alert(x); // 0, la valeur n'est pas incrémenté -``` - - -## Autres variantes : ?.(), ?.[] - -`?.` n'est pas un opérateur, mais une construction syntaxique particulière qui fonctionne aussi avec les appels de fonction et les crochets. - -Par exemple, `?.()` est utilisé pour exécuter une fonction seulement si elle existe. - -Ainsi dans cet exemple la méthode `admin` n'existe pas pour tout le monde : - -```js run -let userAdmin = { - admin() { - alert("I am admin"); - } -}; - -let userGuest = {}; - -*!* -userAdmin.admin?.(); // I am admin -*/!* - -*!* -userGuest.admin?.(); // nothing (no such method) -*/!* -``` - - -Ici, dans les deux lignes, nous utilisons d'abord le point (`user1.admin`) pour obtenir la propriété `admin`, car l'objet utilisateur doit exister, donc il peut être lu en toute sécurité. -Puis `?.()` Vérifie la partie gauche : si la fonction admin existe, alors elle s'exécute (c'est le cas pour `user1`). Sinon (pour `user2`) l'évaluation s'arrête sans erreur. - - -La syntaxe `?.[]` Fonctionne également, si nous voulons utiliser des crochets `[]` pour accéder aux propriétés au lieu du point `.`. Similaire aux cas précédents, il permet de lire en toute sécurité une propriété à partir d'un objet qui peut ne pas exister. - -```js run -let user1 = { - firstName: "John" -}; - -let user2 = null; // Imaginez, nous ne pouvons pas autoriser l'utilisateur - -let key = "firstName"; - -alert( user1?.[key] ); // John -alert( user2?.[key] ); // undefined - -alert( user1?.[key]?.something?.not?.existing); // undefined -``` - -Nous pouvons également utiliser `?.` avec `delete` : - -```js run -delete user?.name; // supprime user.name si user existe -``` - - -```warn header="Nous pouvons utiliser `?.` pour lire et supprimer en toute sécurité, mais pas pour écrire" -Le chaînage optionnel `?.` n'a aucune utilité sur le côté gauche d'une affectation : - - -For example: -```js run - -let user = null; - -user?.name = "John"; // Erreur, ne fonctionne pas -// car il évalue à undefined = "John" -``` -Ce n'est tout simplement pas si intelligent. - -## Résumé - -Le chaînage optionnel '?.' A trois formes : - -1. `obj?.prop` -- retourne `obj.prop` si `obj` existe, sinon `undefined`. -2. `obj?.[prop]` -- retourne `obj[prop]` si `obj` existe, sinon `undefined`. -3. `obj?.method()` -- appel `obj.method()` si `obj.method` existe, sinon retourne `undefined`. - - -Comme nous pouvons le voir, tous sont simples et simples à utiliser. Le `?.` vérifie la partie gauche pour `nul/undefined` et permet à l'évaluation de se poursuivre si ce n'est pas le cas. - -Une chaîne de `?.` permet d'accéder en toute sécurité aux propriétés imbriquées. - - -Néanmoins, nous devons appliquer «?.» Avec soin, uniquement s'il est acceptable que la partie gauche n'existe pas. Pour ne pas nous cacher les erreurs de programmation, si elles se produisent.