Maison >interface Web >js tutoriel >Un guide de l'affectation et de la mutation variables en JavaScript

Un guide de l'affectation et de la mutation variables en JavaScript

尊渡假赌尊渡假赌尊渡假赌
尊渡假赌尊渡假赌尊渡假赌original
2025-02-10 10:35:09464parcourir

Un guide de l'affectation et de la mutation variables en JavaScript

Les mutations sont quelque chose que vous entendez assez souvent dans le monde du javascript, mais que sont-ils exactement, et sont-ils aussi mauvais qu'ils sont faits pour être?

Dans cet article, nous allons couvrir les concepts de l’affectation et de la mutation variables et voir pourquoi - ensemble - ils peuvent être une vraie douleur pour les développeurs. Nous examinerons comment les gérer pour éviter les problèmes, comment utiliser le moins possible et comment garder votre code prévisible.

Si vous souhaitez explorer ce sujet plus en détail ou vous mettre au courant avec JavaScript moderne, consultez le premier chapitre de mon nouveau livre Apprenez à coder avec JavaScript gratuitement.

Commençons par revenir aux bases mêmes des types de valeur…

Les plats clés

  • Les valeurs JavaScript sont classées en primitives (immuables) et objets (mutables), ce qui a un impact sur la façon dont l'affectation et la mutation variables se comportent.
  • L'utilisation de `const 'n'empêche pas les mutations d'objets; Il empêche uniquement la réaffectation de la variable à une valeur ou un objet différent.
  • Le mot clé «Let» permet de réaffectation, ce qui le rend adapté aux variables qui doivent modifier la valeur tout au long du code.
  • L'opérateur de propagation (`…`) est crucial pour créer des copies peu profondes d'objets, évitant ainsi les problèmes liés aux mutations dans les objets copiés par référence.
  • Les mutations ne sont pas intrinsèquement mauvaises mais doivent être gérées avec soin pour maintenir la prévisibilité du code et minimiser les bogues, en particulier dans les applications Web dynamiques.

Types de données

Chaque valeur en JavaScript est soit une valeur primitive, soit un objet. Il existe sept types de données primitifs différents:

  • nombres, tels que 3, 0, -4, 0,625
  • chaînes, comme «bonjour», «monde», «hi», ''
  • booléens, vrai et faux
  • null
  • Undefined
  • Symboles - Un jeton unique garanti de ne jamais affronter un autre symbole
  • BigInt - Pour gérer les grandes valeurs entières

Tout ce qui n'est pas une valeur primitive est un objet, y compris les tableaux, les dates, les expressions régulières et, bien sûr, les littéraux d'objet. Les fonctions sont un type spécial d'objet. Ce sont définitivement des objets, car ils ont des propriétés et des méthodes, mais ils peuvent également être appelés.

Affectation variable

L'affectation variable est l'une des premières choses que vous apprenez dans le codage. Par exemple, c'est ainsi que nous attribuerions le numéro 3 aux ours variables:

<span>const bears = 3;
</span>

Une métaphore commune pour les variables est l'une des cases avec des étiquettes qui ont des valeurs placées à l'intérieur. L'exemple ci-dessus serait représenté comme une boîte contenant l'étiquette «Bears» avec la valeur de 3 placée à l'intérieur.

Un guide de l'affectation et de la mutation variables en JavaScript

Une autre façon de penser à ce qui se passe est une référence, qui mappe que l'étiquette porte à la valeur de 3:

Un guide de l'affectation et de la mutation variables en JavaScript

Si j'attribue le numéro 3 à une autre variable, il fait référence à la même valeur que Bears:

<span>const bears = 3;
</span>

Un guide de l'affectation et de la mutation variables en JavaScript

Les variables ours et les mousquetaires font tous deux référence à la même valeur primitive de 3. Nous pouvons le vérifier en utilisant l'opérateur d'égalité strict, ===:

<span>let musketeers = 3;
</span>

L'opérateur d'égalité renvoie true si les deux variables font référence à la même valeur.

quelques gotchas lorsque vous travaillez avec des objets

Les exemples précédents ont montré que les valeurs primitives étaient affectées aux variables. Le même processus est utilisé lors de l'attribution d'objets:

bears <span>=== musketeers
</span><span><< true
</span>

Cette affectation signifie que la variable Ghostbusters fait référence à un objet:

Un guide de l'affectation et de la mutation variables en JavaScript

Une grande différence lors de l'attribution d'objets aux variables, cependant, est que si vous affectez un autre objet littéral à une autre variable, il référenra un objet complètement différent - même si les deux littéraux d'objets se ressemblent exactement! Par exemple, l'affectation ci-dessous ressemble à la variable TMNT (Teenage Mutant Ninja Turtles) fait référence au même objet que la variable Ghostbusters:

<span>const ghostbusters = { number: 4 };
</span>

Même si les variables Ghostbusters et TMNT semblent référencer le même objet, ils font en fait à la fois référence à un objet complètement différent, car nous pouvons le voir si nous vérifions avec le strict Equality Operator:

<span>let tmnt = { number: 4 };
</span>

Un guide de l'affectation et de la mutation variables en JavaScript

Réaffectation variable

Lorsque le mot-clé const a été introduit dans ES6, de nombreuses personnes croyaient à tort que des constantes avaient été introduites à JavaScript, mais ce n'était pas le cas. Le nom de ce mot-clé est un peu trompeur.

Toute variable déclarée avec const ne peut pas être réaffectée à une autre valeur. Cela vaut pour les valeurs et objets primitifs. Par exemple, la variable Bears a été déclarée en utilisant Const dans la section précédente, il ne peut donc pas avoir une autre valeur qui lui est attribuée. Si nous essayons d'attribuer le numéro 2 aux ours de variables, nous obtenons une erreur:

ghostbusters <span>=== tmnt
</span><span><< false
</span>

La référence au nombre 3 est fixe et la variable Bears ne peut pas être réaffectée une autre valeur.

La même chose s'applique aux objets. Si nous essayons d'attribuer un objet différent à la variable Ghostbusters, nous obtenons la même erreur:

bears <span>= 2;
</span><span><< TypeError: Attempted to assign to readonly property.
</span>

Réaffectation de la variable à l'aide de LET

Lorsque le mot clé LET est utilisé pour déclarer une variable, il peut être réaffecté pour référencer une valeur différente plus tard dans notre code. Par exemple, nous avons déclaré les mousquetaires variables à l'aide de LET, afin que nous puissions modifier la valeur que les mousquetaires font référence. Si D’Artagnan rejoignait les mousquetaires, leur nombre augmenterait à 4:

ghostbusters <span>= {number: 5};
</span><span>TypeError: Attempted to assign to readonly property.
</span>

Un guide de l'affectation et de la mutation variables en JavaScript

Cela peut être fait car let a été utilisé pour déclarer la variable. Nous pouvons modifier la valeur que les mousquetaires font référence autant de fois que nous le souhaitons.

La variable TMNT a également été déclarée en utilisant LET, donc elle peut également être réaffectée pour référencer un autre objet (ou un type différent entièrement si nous le souhaitons):

<span>const bears = 3;
</span>

Notez que la variable TMNT fait désormais référence à un objet complètement différent ; Nous n'avons pas seulement changé la propriété du nombre en 5.

En résumé, si vous déclarez une variable utilisant const, sa valeur ne peut pas être réaffectée et référencera toujours à la même valeur ou objet primitif auquel il a été initialement attribué. Si vous déclarez une variable en utilisant LET, sa valeur peut être réaffectée autant de fois que requise plus loin dans le programme.

L'utilisation de const le plus souvent possible est généralement considérée comme une bonne pratique, car cela signifie que la valeur des variables reste constante et que le code est plus cohérent et prévisible, ce qui le rend moins sujet aux erreurs et aux bogues.

Affectation de variable par référence

Dans JavaScript natif, vous ne pouvez attribuer des valeurs qu'aux variables. Vous ne pouvez pas attribuer des variables pour référencer une autre variable, même si vous semblez que vous le pouvez. Par exemple, le nombre de Stooges est le même que le nombre de mousquetaires, nous pouvons donc affecter les comptes de variables pour faire référence à la même valeur que les mousquetaires variables en utilisant les éléments suivants:

<span>let musketeers = 3;
</span>
Cela ressemble à la variable Stooges fait référence aux mousquetaires variables, comme indiqué dans le diagramme ci-dessous:

Un guide de l'affectation et de la mutation variables en JavaScript

Cependant, cela est impossible dans JavaScript natif: une variable ne peut faire référence qu'une valeur réelle; Il ne peut pas référencer une autre variable. Ce qui se passe réellement lorsque vous effectuez une affectation comme celle-ci, c'est que la variable à gauche de l'affectation référendra la valeur de la variable sur les références de droite, de sorte que la variable Stooges fera référence à la même valeur que la variable Musketeers, qui est le numéro 3 .

Un guide de l'affectation et de la mutation variables en JavaScript

Cela signifie que si D'Artagnan rejoint les mousquetaires et que nous définissons la valeur des mousquetaires à 4, la valeur des Stooges restera 3. En fait, parce que nous avons déclaré la variable de Stooges en utilisant const, nous ne pouvons pas définir à toute nouvelle valeur; ce sera toujours 3.

En résumé: si vous déclarez une variable utilisant const et la définissez sur une valeur primitive, même via une référence à une autre variable, sa valeur ne peut pas changer. C'est bon pour votre code, car cela signifie qu'il sera plus cohérent et prévisible.

Mutations

Une valeur est dite

mutable si elle peut être modifiée. C'est tout ce qu'il y a: une mutation est l'acte de modifier les propriétés d'une valeur.

Toute valeur primitive en javascript est immuable : Vous ne pouvez pas modifier leurs propriétés - jamais. Par exemple, si nous attribuons la chaîne "gâteau" à des aliments variables, nous pouvons voir que nous ne pouvons modifier aucune de ses propriétés:

<span>const bears = 3;
</span>

Si nous essayons de changer la première lettre en «F», il semble que cela ait changé:

<span>let musketeers = 3;
</span>

Mais si nous jetons un coup d'œil à la valeur de la variable, nous voyons que rien n'a réellement changé:

bears <span>=== musketeers
</span><span><< true
</span>

La même chose se produit si nous essayons de changer la propriété de longueur:

<span>const ghostbusters = { number: 4 };
</span>

Malgré la valeur de retour en impliquant que la propriété de longueur a été modifiée, un contrôle rapide montre qu'il n'a pas:

<span>let tmnt = { number: 4 };
</span>

Notez que cela n'a rien à voir avec la déclaration de la variable en utilisant const au lieu de LET. Si nous avions utilisé LET, nous pouvions régler la nourriture pour référencer une autre chaîne, mais nous ne pouvons modifier aucune de ses propriétés. Il est impossible de modifier les propriétés des types de données primitifs car ils sont immuables .

Mutabilité et objets dans JavaScript

Inversement, tous les objets en JavaScript sont mutables, ce qui signifie que leurs propriétés peuvent être modifiées, même si elles sont déclarées à l'aide de const (n'oubliez pas que let et const contrôlent seulement si une variable peut être réaffectée et n'a rien à voir avec mutabilité). Par exemple, nous pouvons modifier le premier élément d'un tableau en utilisant le code suivant:

ghostbusters <span>=== tmnt
</span><span><< false
</span>

Notez que ce changement s'est toujours produit, malgré le fait que nous avons déclaré la nourriture variable à l'aide de const. Cela montre que l'utilisation de const n'empêche pas les objets d'être mutés .

Nous pouvons également modifier la propriété de longueur d'un tableau, même si elle a été déclarée en utilisant const:

bears <span>= 2;
</span><span><< TypeError: Attempted to assign to readonly property.
</span>

Copie par référence

N'oubliez pas que lorsque nous attribuons des variables aux littéraux d'objet, les variables référenceront des objets complètement différents, même s'ils se ressemblent:

ghostbusters <span>= {number: 5};
</span><span>TypeError: Attempted to assign to readonly property.
</span>

Un guide de l'affectation et de la mutation variables en JavaScript

Mais si nous attribuons une variable fantastique4 à une autre variable, ils feront tous deux référence à l'objet même :

musketeers <span>= 4;
</span>

Cela affecte la variable Fantastic4 à référence l'objet > que la variable TMNT fait référence, plutôt qu'un objet complètement différent.

Un guide de l'affectation et de la mutation variables en JavaScript

Ceci est souvent appelé copie par référence, car les deux variables sont attribuées pour référencer l'objet même .

Ceci est important, car toutes les mutations faites à cet objet seront vues dans à la fois variables.

Donc, si Spider-Man rejoint les quatre fantastiques, nous pourrions mettre à jour la valeur du nombre dans l'objet:

tmnt <span>= {number: 5};
</span>

Il s'agit d'une mutation, car nous avons modifié la propriété du numéro plutôt que de définir Fantastic4 pour référencer un nouvel objet.

Cela nous cause un problème, car la propriété du nombre de TMNT changera également, peut-être sans que nous nous réalisions:

<span>const bears = 3;
</span>

En effet

Cela met en évidence un concept important dans JavaScript: lorsque les objets sont copiés par référence et mutés par la suite, la mutation affectera toutes les autres variables qui font référence à cet objet. Cela peut entraîner des effets secondaires involontaires et des bogues difficiles à retrouver.

l'opérateur de propagation à la rescousse!

Alors, comment faites-vous une copie d'un objet sans créer de référence à l'objet d'origine? La réponse est d'utiliser l'opérateur de propagation!

L'opérateur de propagation a été introduit pour les tableaux et les chaînes dans ES2015 et pour les objets dans ES2018. Il vous permet de créer facilement une copie peu profonde d'un objet sans créer de référence à l'objet d'origine.

L'exemple ci-dessous montre comment nous pourrions définir la variable Fantastic4 pour référencer une copie de l'objet TMNT. Cette copie sera exactement la même que l'objet TMNT, mais Fantastic4 fera référence à un tout nouvel objet. Cela se fait en plaçant le nom de la variable à copier à l'intérieur d'un objet littéral avec l'opérateur de propagation devant lui:

<span>let musketeers = 3;
</span>
Ce que nous avons réellement fait ici est d'attribuer la variable Fantastic4 à un nouvel objet littéral, puis a utilisé l'opérateur de diffusion pour copier toutes les propriétés énumérables de l'objet référencé par la variable TMNT. Parce que ces propriétés sont des valeurs, elles sont copiées dans l'objet fantastique4 par valeur, plutôt que par référence.

Un guide de l'affectation et de la mutation variables en JavaScript

Maintenant, toutes les modifications apportées à l'un ou l'autre objet n'affecteront pas l'autre. Par exemple, si nous mettons à jour la propriété numéro de la variable Fantastic4 à 5, cela n'affectera pas la variable TMNT:

bears <span>=== musketeers
</span><span><< true
</span>

Un guide de l'affectation et de la mutation variables en JavaScript

L'opérateur de diffusion a également une notation de raccourci utile qui peut être utilisée pour fabriquer des copies d'un objet, puis apporter quelques modifications au nouvel objet dans une seule ligne de code.

Par exemple, disons que nous voulions créer un objet pour modéliser les tortues ninja mutantes adolescentes. Nous pourrions créer le premier objet Turtle et y attribuer la variable Leonardo:

<span>const ghostbusters = { number: 4 };
</span>
Les autres tortues ont toutes les mêmes propriétés, à l'exception des propriétés d'armes et de couleurs, qui sont différentes pour chaque tortue. Il est logique de faire une copie de l'objet que Leonardo fait référence, à l'aide de l'opérateur de propagation, puis de modifier les propriétés de l'arme et des couleurs, comme ainsi:

<span>let tmnt = { number: 4 };
</span>
Nous pouvons le faire en une seule ligne en ajoutant les propriétés que nous voulons modifier après la référence à l'objet Spread. Voici le code pour créer de nouveaux objets pour les variables Donatello et Raphael:

<span>const bears = 3;
</span>

Notez que l'utilisation de l'opérateur de diffusion de cette manière ne fait qu'une copie peu profonde d'un objet. Pour en faire une copie profonde, vous devez le faire récursivement ou utiliser une bibliothèque. Personnellement, je vous conseille d'essayer de garder vos objets aussi superficiels que possible.

Les mutations sont-elles mauvaises?

Dans cet article, nous avons couvert les concepts d'attribution et de mutation variables et vu pourquoi - ensemble - ils peuvent être une vraie douleur pour les développeurs.

Les mutations

ont une mauvaise réputation, mais elles ne sont pas nécessairement mauvaises en elles-mêmes. En fait, si vous créez une application Web dynamique, elle doit changer à un moment donné. C’est littéralement le sens du mot «dynamique»! Cela signifie qu'il devra y avoir des mutations quelque part dans votre code. Cela dit, moins il y a de mutations, plus votre code sera prévisible, ce qui facilite le maintien et les moins susceptibles de développer des bogues.

Une combinaison particulièrement toxique est la copie par référence et mutations. Cela peut entraîner des effets secondaires et des bugs que vous ne réalisez même pas. Si vous mutez un objet référencé par une autre variable de votre code, cela peut causer de nombreux problèmes qui peuvent être difficiles à retrouver. La clé est d'essayer de minimiser votre utilisation de mutations à l'essentiel et de suivre les objets mutés.

Dans la programmation fonctionnelle, une fonction pure est celle qui ne provoque aucun effet secondaire, et les mutations sont l'une des plus grandes causes d'effets secondaires.

Une règle d'or consiste à éviter de copier des objets par référence. Si vous souhaitez copier un autre objet, utilisez l'opérateur de diffusion, puis faites des mutations immédiatement après avoir fait la copie.

Next up, nous examinerons les mutations du tableau en javascript.

N'oubliez pas de consulter mon nouveau livre Apprenez à coder avec JavaScript si vous souhaitez vous mettre au courant avec JavaScript moderne. Vous pouvez lire gratuitement le premier chapitre. Et veuillez contacter sur Twitter si vous avez des questions ou des commentaires!

Questions fréquemment posées (FAQ) sur l'affectation et la mutation des variables JavaScript

Quelle est la différence entre l'affectation et la mutation variables dans JavaScript?

Dans JavaScript, l'attribution de variable fait référence au processus d'attribution d'une valeur à une variable. Par exemple, laissez x = 5; Ici, nous attribuons la valeur 5 à la variable x. D'un autre côté, la mutation fait référence au processus de modification de la valeur d'une variable existante. Par exemple, si nous écrivons plus tard x = 10; Nous mutins la variable x en changeant sa valeur de 5 à 10.

Comment JavaScript gère la tâche et la mutation variables différemment pour les types de données primitifs et non primitifs?

JavaScript traite les types de données primitifs (comme les nombres, les chaînes et les booléens) et les types de données non primitives (comme des objets comme des objets et tableaux) différemment en ce qui concerne l'attribution et la mutation variables. Pour les types de données primitifs, lorsque vous affectez une variable, une copie de la valeur est créée et stockée dans un nouvel emplacement de mémoire. Cependant, pour les types de données non primitives, lorsque vous attribuez une variable, les deux variables pointent vers le même emplacement de mémoire. Par conséquent, si vous mutez une variable, le changement se reflète dans toutes les variables qui pointent vers cet emplacement de mémoire.

Quel est le concept de la valeur pass-par-valeur et de la référence dans JavaScript?

Pass-by-Value et Pass-by-Reference sont deux façons dont JavaScript peut transmettre des variables à une fonction. Lorsque JavaScript passe une variable par valeur, il crée une copie de la valeur de la variable et transmet cette copie à la fonction. Toutes les modifications apportées à la variable à l'intérieur de la fonction n'affectent pas la variable d'origine. Cependant, lorsque JavaScript passe une variable par référence, il transmet une référence à l'emplacement de mémoire de la variable. Par conséquent, toutes les modifications apportées à la variable à l'intérieur de la fonction affectent également la variable d'origine.

Comment puis-je empêcher la mutation en JavaScript?

Il existe plusieurs façons d'empêcher la mutation en JavaScript. Une façon consiste à utiliser la méthode object.freeze (), qui empêche les nouvelles propriétés d'être ajoutées à un objet, les propriétés existantes d'être supprimées et empêchent la modification de l'énumérabilité, de la configurabilité ou de l'écriture des propriétés existantes. Une autre façon consiste à utiliser le mot clé const lors de la déclaration d'une variable. Cela empêche la réaffectation de la variable, mais elle n'empêche pas la mutation de la valeur de la variable si la valeur est un objet ou un tableau.

Quelle est la différence entre une copie superficielle et une copie profonde en javascript?

Dans JavaScript, une copie peu profonde d'un objet est une copie de l'objet où les valeurs de l'objet d'origine et le point de copie au même emplacement de mémoire pour les types de données non primitives. Par conséquent, si vous mutez la copie, l'objet d'origine est également muté. D'un autre côté, une copie profonde d'un objet est une copie de l'objet où les valeurs de l'objet d'origine et la copie ne pointent pas vers le même emplacement de mémoire. Par conséquent, si vous mutez la copie, l'objet d'origine n'est pas muté.

Comment puis-je créer une copie profonde d'un objet en javascript?

Une façon de créer une copie profonde d'un objet Dans JavaScript, consiste à utiliser les méthodes JSON.Parse () et JSON.Strinify (). La méthode json.stringify () convertit l'objet en une chaîne JSON, et la méthode JSON.Parse () convertit la chaîne JSON en un objet. Cela crée un nouvel objet qui est une copie profonde de l'objet d'origine.

Quelle est l'API MutationObserver dans JavaScript?

L'API MutationObserver fournit aux développeurs un moyen de réagir aux changements dans un DOM. Il est conçu pour fournir une API générale, efficace et robuste pour réagir aux changements dans un document.

Comment JavaScript gère-t-il l'affectation et la mutation variables dans le contexte des fermetures?

En JavaScript, Une fermeture est une fonction qui a accès à sa propre portée, à la portée de la fonction extérieure et à la portée globale. Lorsqu'une variable est attribuée ou mutée à l'intérieur d'une fermeture, elle peut affecter la valeur de la variable dans la portée extérieure, selon que la variable a été déclarée dans la portée de la fermeture ou la portée extérieure.

Quelle est la différence Entre var, let et const dans JavaScript?

Dans JavaScript, var, let et const, sont utilisés pour déclarer les variables. VAR est dans la fonction de fonction, et si elle est déclarée en dehors d'une fonction, elle est à l'échelle mondiale. Selt et const sont dans le blocage du bloc, ce qui signifie qu'ils n'existent que dans le bloc dans lequel ils sont déclarés. La différence entre LET et const est que LET permet de réaffectation, tandis que Const ne fait pas.

comment JavaScript gère l'attribution et la mutation variables Dans le contexte de la programmation asynchrone?

En JavaScript, la programmation asynchrone permet à plusieurs choses de se produire en même temps. Lorsqu'une variable est attribuée ou mutée dans une fonction asynchrone, elle peut conduire à des résultats inattendus si d'autres parties du code s'appuient sur la valeur de la variable. En effet, l'affectation ou la mutation variable peut ne pas avoir terminé avant l'exécution des autres parties du code. Pour gérer cela, JavaScript fournit plusieurs fonctionnalités, telles que les promesses et les asynchrones / attendre, pour aider à gérer le code asynchrone.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn