Cet article suit le guide d'attribution et de mutation de la variable JavaScript et discute des problèmes et des solutions apportés par la méthode du tableau muté. De nombreuses méthodes de tableau JavaScript modifient directement le tableau d'origine, ce qui peut facilement conduire à des bogues difficiles à transformer dans les grandes applications. Mais toutes les méthodes ne sont pas comme celle-ci. Pour éviter des mutations inattendues, nous pouvons écrire nos propres méthodes de tableau immuables qui renvoient de nouveaux objets de tableau au lieu de modifier le tableau d'origine. Cet article couvrira des versions immuables de méthodes telles que Array.prototype.slice()
, Array.prototype.concat()
, Array.prototype.map()
, Array.prototype.filter()
, pop
, push
, et shift
. L'utilisation de méthodes de tableau immuables peut écrire plus claire et plus facile à maintenir le code pour éviter les bogues causés par les effets secondaires. unshift
reverse
splice
Mutation du tableau dans JavaScript
Les tableaux JavaScript sont des objets et peuvent donc être modifiés. De nombreuses méthodes de tableau intégré modifient directement le tableau lui-même, ce qui viole les meilleures pratiques en matière de programmation. L'exemple suivant montre un problème potentiel:
Ce code semble normal. En surface, cela fonctionne:
const numbers = [1,2,3]; const countdown = numbers.reverse();
mais la méthode numbers
a également modifié le tableau countdown
, ce qui n'est pas le résultat que nous voulons: numbers
countdown // [3, 2, 1]
pour ajouter un élément avec une valeur de 0 à la fin du tableau reverse()
, le tableau numbers
changera également de la même manière (car ils se réfèrent tous au même tableau):
numbers // [3, 2, 1]
Cet effet secondaire est facilement négligé dans les grandes applications et conduit à des bogues difficiles à suivre. Array.prototype.push()
countdown
numbers
Méthode du tableau variable dans JavaScript
countdown.push(0) countdown // [3, 2, 1, 0] numbers // [3, 2, 1, 0]
En plus de
, il existe de nombreuses autres méthodes de tableau qui provoquent cette mutation:
reverse()
Array.prototype.pop()
Array.prototype.push()
Array.prototype.shift()
Array.prototype.unshift()
Array.prototype.reverse()
Array.prototype.sort()
En revanche, certaines méthodes ne modifient pas le tableau d'origine, mais renvoient un nouveau tableau: Array.prototype.slice()
Array.prototype.concat()
Array.prototype.map()
Array.prototype.filter()
Ces méthodes renvoient un nouveau tableau basé sur les actions effectuées. Par exemple, la méthode map()
peut être utilisée pour doubler tous les nombres dans un tableau:
const numbers = [1,2,3]; const countdown = numbers.reverse();
Maintenant, si nous vérifions le tableau numbers
, nous pouvons voir qu'il n'est pas affecté par l'appel de la méthode:
countdown // [3, 2, 1]
Pourquoi certaines méthodes modifient-elles les tableaux, tandis que d'autres ne le font pas? Il ne semble pas y avoir de raison claire à cela, mais les méthodes récemment ajoutées ont tendance à la rendre immuable. Il peut être difficile de se rappeler quelles méthodes modifieront le tableau et quelles méthodes ne modifieront pas le tableau.
Méthode du tableau immuable: Correction du problème de mutation
Nous avons déterminé que les mutations peuvent causer des problèmes et que de nombreuses méthodes de tableau provoqueront des mutations. Voyons comment éviter de les utiliser. Il n'est pas difficile d'écrire certaines fonctions qui renvoient de nouveaux objets de tableau au lieu de modifier le tableau d'origine. Ces fonctions sont nos méthodes de tableau immuables.
Parce que nous ne modifierons pas Array.prototype
, ces fonctions prennent toujours le tableau lui-même comme le premier paramètre.
pop
Commençons par écrire une nouvelle fonction pop
qui renvoie une copie du tableau d'origine mais ne contient pas le dernier élément. Notez que Array.prototype.pop()
renvoie la valeur éclatée de la fin du tableau:
numbers // [3, 2, 1]
Cette fonction utilise Array.prototype.slice()
pour renvoyer une copie du tableau, mais supprime le dernier élément. Le deuxième paramètre -1 signifie "Arrêtez la tranche, 1 position avant la fin". Nous pouvons voir comment cela fonctionne dans l'exemple suivant:
countdown.push(0) countdown // [3, 2, 1, 0] numbers // [3, 2, 1, 0]
push
Ensuite, créons une fonction push()
qui renverra un nouveau tableau, mais ajoutez un nouvel élément à la fin:
const numbers = [1,2,3]; const evens = numbers.map(number => number * 2);
Cela crée une copie du tableau à l'aide de l'opérateur d'extension. Il ajoute ensuite la valeur fournie comme le deuxième paramètre à la fin du nouveau tableau. Voici un exemple:
numbers // [1, 2, 3]
shift
et unshift
Nous pouvons écrire des alternatives à Array.prototype.shift()
et Array.prototype.unshift()
de même:
const pop = array => array.slice(0,-1);
Pour notre fonction shift()
, nous venons de couper le premier élément du tableau au lieu du dernier élément. Cela peut être vu dans l'exemple suivant:
const food = ['?','?','?','?']; pop(food) // ['?','?','?']
Notre méthode unshift()
renverra un nouveau tableau et ajoutera une nouvelle valeur au début du tableau:
const push = (array, value) => [...array,value];
étendu nous permet de placer des valeurs dans un tableau dans n'importe quel ordre. Nous devons simplement mettre la nouvelle valeur devant la copie d'origine du tableau. Nous pouvons voir comment cela fonctionne dans l'exemple suivant:
const food = ['?','?','?','?']; push(food,'?') // ['?','?','?','?','?']
reverse
Essayons maintenant d'écrire une alternative à la méthode Array.prototype.reverse()
. Il renverra une copie du tableau disposé dans l'ordre inverse, plutôt que de modifier le tableau d'origine:
const numbers = [1,2,3]; const countdown = numbers.reverse();
Cette méthode utilise toujours la méthode Array.prototype.reverse()
, mais s'applique à une copie du tableau d'origine que nous créons à l'aide de l'opérateur d'extension. Il n'y a aucun problème à modifier l'objet juste après sa création, et c'est ce que nous faisons ici. Nous pouvons voir comment cela fonctionne dans l'exemple suivant:
countdown // [3, 2, 1]
splice
Enfin, traitons avec Array.prototype.splice()
. Il s'agit d'une fonction très générale, donc nous ne réécrivons pas complètement ses fonctionnalités (bien que ce soit un exercice intéressant). Au lieu de cela, nous nous concentrerons sur deux utilisations principales de slice
: supprimer des éléments des tableaux et insérer des éléments dans les tableaux.
Supprimer les éléments du tableau
Commençons par une fonction qui renvoie un nouveau tableau, mais supprimez un élément à l'index donné:
numbers // [3, 2, 1]
Ceci utilise Array.prototype.slice()
pour couper le tableau en deux - les deux côtés de l'élément que nous voulons supprimer. La première tranche renvoie un nouveau tableau, copiant des éléments du tableau d'origine jusqu'à ce que l'index soit spécifié comme l'index du paramètre. La deuxième tranche renvoie un tableau contenant les éléments que nous voulons supprimer, jusqu'à la fin du tableau d'origine. Nous utilisons ensuite l'opérateur d'extension pour les mettre tous dans un nouveau tableau. Nous pouvons vérifier si cela fonctionne en essayant de supprimer l'élément avec l'index 2 dans le tableau food
ci-dessous:
countdown.push(0) countdown // [3, 2, 1, 0] numbers // [3, 2, 1, 0]
Ajouter des éléments du tableau
Enfin, écrivons une fonction qui renverra un nouveau tableau et inséra une nouvelle valeur à un index spécifique:
const numbers = [1,2,3]; const evens = numbers.map(number => number * 2);
Ceci est similaire à la façon dont la fonction remove()
fonctionne. Il crée deux tranches du tableau, mais cette fois comprend les éléments de l'indice fourni. Lorsque nous regroupons les deux tranches ensemble, nous insérons la valeur fournie comme le paramètre entre elles. Nous pouvons vérifier si cela fonctionne en essayant d'insérer un emoji cupcake au milieu de notre tableau food
:
numbers // [1, 2, 3]
Maintenant, nous avons un ensemble immuable de méthodes de tableau qui ne modifient pas le tableau d'origine. Vous pouvez les enregistrer en un seul endroit et les utiliser dans votre projet. Vous pouvez les faire des noms en les prenant en tant que méthode d'objet unique ou les utiliser en cas de besoin. Ces méthodes devraient être suffisantes pour la plupart des opérations de tableau. Si vous devez faire différentes choses, n'oubliez pas la règle d'or: utilisez d'abord l'opérateur d'extension pour créer une copie du tableau d'origine. Ensuite, immédiatement appliquez une méthode variable à cette copie.
Conclusion
Dans cet article, nous examinons comment JavaScript rend la vie difficile en modifiant une méthode de tableau qui modifie le tableau d'origine dans le cadre de la langue. Nous avons ensuite écrit notre propre méthode de tableau immuable pour remplacer ces fonctions.
quelles autres méthodes de tableau pouvez-vous penser qui peuvent bénéficier d'une version immuable?
FAQ sur la création et l'utilisation de méthodes de tableau immuables dans JavaScript
L'invariance est un concept de base de la programmation, qui fait référence à l'état d'un objet qui ne peut pas être modifié après sa création. Dans JavaScript, l'invariance n'est pas appliquée par défaut. Cependant, c'est un concept puissant qui peut vous aider à écrire plus prévisible et plus facile à maintenir le code. Il est particulièrement utile dans la programmation fonctionnelle, où l'invariance empêche les erreurs et la complexité causées par l'évolution des états.
L'utilisation de méthodes de tableau immuables dans JavaScript peut écrire plus clairement et plus facile à maintenir le code. Étant donné que ces méthodes ne modifient pas le tableau d'origine, elles peuvent empêcher les effets secondaires qui peuvent provoquer des erreurs. Ceci est particulièrement important dans les grandes bases de code ou lorsqu'ils traitent des structures de données complexes. La méthode immuable renvoie un nouveau tableau, tandis que le tableau d'origine reste inchangé. Cela rend votre code plus prévisible et plus facile à déboguer.
JavaScript fournit des méthodes de tableau immuables qui ne modifient pas le tableau d'origine. Certains exemples incluent les méthodes map()
, filter()
, reduce()
et concat()
. La méthode map()
crée un nouveau tableau contenant les résultats de la fonction fournie pour chaque élément du tableau. La méthode filter()
crée un nouveau tableau contenant tous les éléments du test implémenté par la fonction fournie. La méthode reduce()
applique une fonction à chaque élément de l'accumulateur et du tableau pour le réduire à une seule valeur de sortie. La méthode concat()
est utilisée pour fusionner deux tableaux ou plus et renvoyer un nouveau tableau.
JavaScript ne fournit pas de méthode intégrée pour rendre les tableaux immuables. Cependant, vous pouvez réaliser l'invariance en utilisant des méthodes qui ne modifient pas le tableau d'origine (par exemple map()
, filter()
, reduce()
et concat()
). Une autre approche consiste à utiliser la méthode Object.freeze()
, qui empêche l'ajout de nouvelles propriétés à l'objet, empêche l'élimination des propriétés existantes et empêche l'énumération, la configurabilité ou l'écriture des propriétés existantes.
La principale différence entre les méthodes mutables et immuables en JavaScript est la façon dont ils gèrent le tableau d'origine. Une méthode mutable modifie le tableau d'origine, contrairement à une méthode immuable. Au lieu de cela, la méthode immuable renvoie un nouveau tableau. Cela rend votre code plus prévisible et plus facile à déboguer car il empêche les effets secondaires qui peuvent provoquer des erreurs.
Oui, vous pouvez utiliser des tableaux immuables avec d'autres types de données en JavaScript. Le concept d'invariance s'applique à tous les types de données, pas seulement aux tableaux. Par exemple, vous pouvez utiliser des méthodes immuables avec des chaînes, des nombres, des objets, etc. Cela peut vous aider à écrire plus clair et plus facile à maintenir le code.
L'utilisation de méthodes de tableau immuables peut avoir un certain impact sur les performances, car ils créent généralement un nouveau tableau au lieu de modifier le tableau d'origine. Cela peut entraîner une utilisation accrue de la mémoire, en particulier dans les grandes tableaux. Cependant, dans la plupart des cas, les avantages de l'utilisation de méthodes immuables, telles que du code plus clair et moins de bogues, l'emportent sur les coûts de performance potentiels.
reduce()
dans JavaScript? La méthode reduce()
en JavaScript est une méthode immuable qui applique une fonction à chaque élément de l'accumulateur et du tableau pour le réduire à une seule valeur de sortie. Voici un exemple de la façon de l'utiliser:
const numbers = [1,2,3]; const countdown = numbers.reverse();
Dans cet exemple, la méthode reduce()
calcule la somme de tous les éléments du tableau.
concat()
en JavaScript? La méthode concat()
dans JavaScript est utilisée pour fusionner deux tableaux ou plus. Cette méthode ne modifie pas le tableau existant, mais renvoie un nouveau tableau. Voici un exemple:
countdown // [3, 2, 1]
Dans cet exemple, la méthode concat()
fusionne array1
et array2
dans un nouveau tableau array3
.
filter()
dans JavaScript? La méthode filter()
dans JavaScript crée un nouveau tableau contenant tous les éléments du test implémenté par la fonction fournie. Voici un exemple de la façon de l'utiliser:
numbers // [3, 2, 1]
Dans cet exemple, la méthode filter()
crée un nouveau tableau contenant des nombres supérieurs à 3.
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!