Maison >interface Web >js tutoriel >Copie profonde contre profonde dans JavaScript
La copie d'objets JavaScript n'est pas aussi simple qu'il n'y paraît. Comprendre le fonctionnement des objets et des références au cours de ce processus pour les développeurs Web et peut économiser des heures de débogage. Cela devient de plus en plus important lorsque vous utilisez de grandes applications avec état, telles que celles intégrées à React ou Vue.
Copie peu profonde et copie profonde se référons à la façon dont nous créons des copies d'objets en javascript et sur les données que nous créons dans "Copier". Dans cet article, nous approfondirons les différences entre ces méthodes, explorerons leurs applications pratiques et découvrirons les pièges potentiels qui peuvent survenir lors de leur utilisation.
La copie superficielle fait référence au processus de création d'un nouvel objet, qui est une copie d'un objet existant dont les propriétés se réfèrent à la même valeur ou objet numérique que l'objet d'origine. En JavaScript, cela est généralement réalisé en utilisant des méthodes telles que Object.assign()
ou syntaxe d'expansion ({...originalObject}
). Une copie peu profonde ne crée que de nouvelles références à des objets ou des valeurs existants, et ne crée pas de copie profonde, ce qui signifie que les objets imbriqués sont toujours référencés, pas des doublons.
Jetons un coup d'œil à l'exemple de code suivant. L'objet nouvellement créé shallowCopyZoo
est une copie de zoo
créée en élargissant l'opérateur, qui a des conséquences inattendues.
<code class="language-javascript">let zoo = { name: "Amazing Zoo", location: "Melbourne, Australia", animals: [ { species: "Lion", favoriteTreat: "?", }, { species: "Panda", favoriteTreat: "?", }, ], }; let shallowCopyZoo = { ...zoo }; shallowCopyZoo.animals[0].favoriteTreat = "?"; console.log(zoo.animals[0].favoriteTreat); // "?",而不是 "?"</code>
Mais voyons ce qui est exactement dans shallowCopyZoo
. Les propriétés name
et location
sont les valeurs d'origine (chaînes), donc leurs valeurs sont copiées. Cependant, la propriété animals
est un tableau d'objets, donc ce qui est copié est une référence à ce tableau, pas au tableau lui-même.
Vous pouvez utiliser l'opérateur d'égalité strict (===
) pour tester cela rapidement (si vous ne me croyez pas). Ce n'est que lorsqu'un objet fait référence au même objet, un objet est égal à un autre objet (voir Types de données primitifs et types de données de référence). Notez que les attributs animals
sont égaux dans les deux, mais l'objet lui-même n'est pas égal.
<code class="language-javascript">let zoo = { name: "Amazing Zoo", location: "Melbourne, Australia", animals: [ { species: "Lion", favoriteTreat: "?", }, { species: "Panda", favoriteTreat: "?", }, ], }; let shallowCopyZoo = { ...zoo }; shallowCopyZoo.animals[0].favoriteTreat = "?"; console.log(zoo.animals[0].favoriteTreat); // "?",而不是 "?"</code>
Cela peut entraîner des problèmes potentiels dans la base de code et est particulièrement difficile lorsqu'il s'agit de grandes modifications. La modification des objets imbriqués dans des répliques peu profondes affecte également l'objet d'origine et toutes les autres répliques peu profondes car elles partagent toutes la même référence.
La copie profonde est une astuce pour créer un nouvel objet qui est une copie exacte d'un objet existant. Cela comprend la copie de toutes ses propriétés et de tous les objets imbriqués, plutôt que des références. Le clonage profond est utile lorsque vous avez besoin de deux objets distincts qui ne partagent pas de références, garantissant que les modifications à un objet n'affectent pas l'autre.
Les programmeurs utilisent souvent un clonage profond lorsqu'ils traitent des objets d'état d'application dans des applications complexes. La création d'un nouvel objet d'état sans affecter l'état précédent est essentiel pour maintenir la stabilité des applications et implémenter correctement la fonctionnalité UNDO / Remo.
JSON.stringify()
et JSON.parse()
pour une copie profonde Une méthode de copie profonde populaire et sans bibliothèque consiste à utiliser les méthodes intégrées JSON.stringify()
et JSON.parse()
.
parse(stringify())
La méthode n'est pas parfaite. Par exemple, des types de données spéciaux tels que Date
seront convertis en chaînes et les valeurs non définies seront ignorées. Comme pour toutes les options de cet article, vous devriez le considérer en fonction de votre cas d'utilisation spécifique.
Dans le code suivant, nous utiliserons ces méthodes pour créer une fonction deepCopy
pour cloner profondément un objet. Ensuite, nous copie l'objet playerProfile
et modifions l'objet copié sans affecter l'objet d'origine. Cela démontre la valeur de la réplication profonde dans le maintien d'objets indépendants qui ne partagent pas de références.
<code class="language-javascript">console.log(zoo.animals === shallowCopyZoo.animals) // true console.log(zoo === shallowCopyZoo) // false</code>
Il existe également une variété de bibliothèques tierces qui fournissent des solutions de réplication profonde.
cloneDeep()
Lodash peuvent gérer correctement les références de boucle, les fonctions et les objets spéciaux. extend()
Fonction de la bibliothèque jQuery [deep = true]
La bibliothèque
<code class="language-javascript">const playerProfile = { name: 'Alice', level: 10, achievements: [ { title: 'Fast Learner', emoji: '?' }, { title: 'Treasure Hunter', emoji: '?' } ] }; function deepCopy(obj) { return JSON.parse(JSON.stringify(obj)); } const clonedProfile = deepCopy(playerProfile); console.log(clonedProfile); // 输出与playerProfile相同 // 修改克隆的配置文件而不影响原始配置文件 clonedProfile.achievements.push({ title: 'Marathon Runner', emoji: '?' }); console.log(playerProfile.achievements.length); // 输出:2 console.log(clonedProfile.achievements.length); // 输出:3</code>Inconvénients d'une copie profonde
Date
, RegExp
, éléments DOM). Par exemple, lors de la copie profonde d'un objet contenant une fonction, une référence à la fonction peut être copiée, mais la fermeture de la fonction et son contexte lié ne sera pas copiée. De même, les objets avec des fonctionnalités spéciales peuvent perdre leurs propriétés et leurs comportements uniques lorsqu'ils sont profondément reproduits. JSON.parse(JSON.stringify(obj))
ont également certaines limites, telles que ne pas être en mesure de gérer correctement les fonctions, des références circulaires ou des objets spéciaux. Bien qu'il existe des bibliothèques tierces telles que Lodash de _.cloneDeep()
qui gèrent la réplication profonde plus efficacement, l'ajout de dépendances externes pour une réplication profonde peut ne pas toujours être idéale. Merci d'avoir pris le temps de lire cet article. La réplication superficielle et profonde est beaucoup plus complexe que tout débutant ne pourrait le penser. Bien qu'il existe de nombreux pièges dans chaque approche, prendre le temps d'examiner et considérer ces options garantira que votre application et vos données conservent à quoi vous voulez ressembler.
La principale différence entre la réplication peu profonde et la réplication profonde est la façon dont ils gèrent les propriétés en tant qu'objets. En copie peu profonde, l'objet copié partage la même référence à l'objet imbriqué que l'objet d'origine. Cela signifie que les changements aux objets imbriqués seront reflétés dans l'objet d'origine et l'objet Copie. La réplication profonde, en revanche, crée de nouvelles instances d'objets imbriqués, ce qui signifie que les changements d'objets imbriqués dans l'objet répliqué n'affectent pas l'objet d'origine.
L'opérateur d'extension (…) en JavaScript est généralement utilisé pour la copie peu profonde. Il copie toutes les propriétés énumérables d'un objet à un autre. Cependant, il copie uniquement les attributs et références de premier niveau à des objets imbriqués. Par conséquent, les modifications des objets imbriqués affecteront l'objet d'origine et l'objet copié.
Oui, vous pouvez utiliser la méthode JSON pour effectuer une copie profonde dans JavaScript. Une combinaison de méthodes JSON.stringify()
et JSON.parse()
crée une copie profonde d'un objet. JSON.stringify()
convertit l'objet en une chaîne, JSON.parse()
analyse la chaîne vers le nouvel objet. Cependant, cette méthode a certaines limites car elle ne copie pas la méthode et ne convient pas aux objets JavaScript spéciaux tels que Date
, RegExp
, Map
, Set
, etc.
La copie peu profonde reproduit uniquement les attributs et références de premier niveau aux objets imbriqués. Par conséquent, si l'objet d'origine contient des objets imbriqués, les modifications de ces objets imbriqués affecteront l'objet d'origine et l'objet copié. Cela peut conduire à des résultats et des erreurs inattendus dans le code.
Object.assign()
Comment fonctionne la méthode en copie superficielle? Object.assign()
est utilisée pour copier les valeurs de toutes les propriétés énumérées d'un ou plusieurs objets source à l'objet cible. Il renvoie l'objet cible. Cependant, il effectue une copie peu profonde, ce qui signifie qu'il copie uniquement les propriétés et références de premier niveau à des objets imbriqués.
La meilleure façon de copier en profondeur des objets en JavaScript dépend des exigences spécifiques du code. Si votre objet ne contient pas de méthodes ou d'objets JavaScript spéciaux, vous pouvez utiliser une combinaison de méthodes JSON.stringify()
et JSON.parse()
. Pour des objets plus complexes, vous voudrez peut-être utiliser des bibliothèques comme Lodash, qui offrent des fonctions de clonage profondes.
Non, l'opérateur d'extension en JavaScript effectue uniquement une copie peu profonde. Il copie l'attribut de premier niveau et fait référence aux objets imbriqués. Pour effectuer une réplication profonde, vous devez utiliser une autre méthode ou bibliothèque.
La réplication profonde peut consommer plus de ressources que la réplication peu profonde, en particulier pour les grands objets. En effet, la copie profonde crée de nouvelles instances pour tous les objets imbriqués, ce qui peut prendre plus de mémoire et de puissance de traitement.
JSON.stringify()
et JSON.parse()
ne gèrent pas les références circulaires et lanceront une erreur. Une référence circulaire se produit lorsque les propriétés d'un objet se réfèrent à l'objet lui-même. Pour gérer les références circulaires, vous devez utiliser une bibliothèque qui le prend en charge, comme Lodash.
Comprendre la différence entre la réplication superficielle et profonde est essentielle pour gérer les données en JavaScript. Cela affecte la façon dont vos objets interagissent les uns avec les autres. Si vous ne faites pas attention, la copie peu profonde peut conduire à des résultats et des erreurs inattendus, car les modifications des objets imbriqués affectent les objets d'origine et copiés. Deep Copy, en revanche, garantit que votre objet de copie est complètement indépendant de l'objet d'origine.
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!