JavaScript Deep Copy est développé par les débutants et même expérimenté, et ils rencontrent souvent des problèmes et ne peuvent pas très bien comprendre la copie profonde JavaScript.
Deepclone?
L'opposé d'une copie profonde est une copie superficielle. De nombreux débutants sont confus lorsqu'ils entrent en contact avec ce sentiment.
Pourquoi utiliser une copie profonde?
Dans de nombreux cas, nous devons attribuer des valeurs aux variables et attribuer une valeur à l'adresse mémoire. Cependant, lors de l'attribution d'un type de valeur de référence, nous partageons uniquement une zone de mémoire, ce qui entraîne la maintenance de la cohérence avec la valeur précédente lors de l'attribution.
Voir un exemple spécifique
// Attribuez un objet pour tester var test = {a: 'a', b: 'b'}; // attribuer le test au test2 // à l'heure actuelle, test et test2 partagent le même objet de mémoire, qui est la copie peu profonde de var test2 = test; test2.a = 'a2'; test.a === 'a2' // est vraiIllustration:
C'est une bonne idée de comprendre pourquoi les données des types de valeur de référence s'influencent mutuellement.
accomplir
Pour implémenter une fonction de copie profonde, nous devons parler du type numérique de JavaScript.
Déterminer le type JavaScript
Il existe les types de base suivants en javascript
DESCRIPTION DE TYPE
Le type non défini-défini n'a qu'une seule valeur non définie, qui est la valeur lorsque la variable n'est pas attribuée.
Nullnull Type n'a également qu'une seule valeur nul, c'est une référence d'objet vide
Booleanboolean a deux valeurs: vrai et faux
Chaîne Il représente les informations textuelles
Numéro Il représente les informations numériques
Objet Il s'agit d'une collection non ordonnée d'une série de propriétés, y compris la fonction de fonction et le tableau du tableau
Il est impossible de juger la fonction et le tableau en utilisant le typeof. Ici, nous utilisons la méthode object.prototype.tostring.
[Par défaut, chaque objet héritera de l'objet à la méthode toString (). Si cette méthode n'est pas écrasée (bloquée) par la même méthode de nom sur l'objet lui-même ou un prototype supérieur plus proche, la méthode TOSTRING () de l'objet sera appelée et que le type de chaîne représente ici un type d'objet] [1]
Type de fonction (obj) {var toString = object.prototype.toString; var map = {'[objet booléen]': 'booléen', '[numéro d'objet]': 'numéro', '[string d'objet]': 'String', '[Fonction Object]': 'Function', '[Object Array]': 'Array', '[Object Date]': 'Date', '[Object Array " 'null', '[objet objet]': 'objet'}; Retour carte [toString.call (obj)];}Implémenter DeepClone
Pour les valeurs numériques des types de valeur non référencés, la valeur est attribuée directement, et pour les types de valeur référencés (objet), vous devez vous traverser à nouveau et attribuer de manière récursive.
fonction DeepClone (data) {var t = type (data), o, i, ni; if (t === 'array') {o = []; } else if (t === 'objet') {o = {}; } else {return data; } if (t === 'array') {for (i = 0, ni = data.length; i <ni; i ++) {o.push (deepclone (data [i])); } retour o; } else if (t === 'objet') {for (i in data) {o [i] = deepClone (data [i]); } retour o; }}Il y a un point ici auquel tout le monde devrait faire attention. Pour les types de fonctions, le blogueur attribue-t-il directement des valeurs ou partage une valeur de mémoire. En effet, les fonctions consistent davantage à remplir certaines fonctions, avec une valeur d'entrée et une valeur de retour, et pour les services de niveau supérieur, ils consistent davantage à remplir les fonctions commerciales, et il n'est pas nécessaire de vraiment copier la fonction profondément.
Mais comment copier le type de fonction?
En fait, le blogueur a seulement pensé à utiliser New pour l'exploiter, mais la fonction sera exécutée une fois, et je n'ose pas imaginer quel sera le résultat d'exécution! O (□) O! Je n'ai pas encore de bonnes idées, donnez-moi des conseils!
À ce stade, la copie profonde a été presque terminée, mais certaines personnes pensent que pourquoi la copie superficielle n'a-t-elle pas été mise en œuvre?
Une copie superficielle?
Pour des copies peu profondes, il peut être compris comme opérant une seule zone de mémoire commune! Il y aura un danger ici! (.. *)
Si vous exploitez ces données partagées directement sans les contrôler, des exceptions de données se produiront souvent et sont modifiées par d'autres parties. Par conséquent, vous ne devez pas utiliser la source de données directement, encapsuler certaines méthodes pour effectuer des opérations de caillé sur les données.
C'est probablement presque la même chose ici, mais en tant que frontal, il ne considère pas seulement JavaScript lui-même, mais aussi le DOM, le navigateur, etc.
Type d'élément
Examinons le code suivant, que sera renvoyé dans le résultat?
Object.prototype.toString.call(document.getElementsByTagName('div')[0])
La réponse est [objet htmlaidement]
Parfois, lorsque l'élément DOM est enregistré et si vous le copiez accidentellement en profondeur, la fonction de copie profonde ci-dessus manque de jugement sur l'élément. Pour juger de l'élément, utilisez l'instance pour juger. Parce que pour différentes balises, ToString renverra le constructeur correspondant à différentes balises.
Type de fonction (obj) {var toString = object.prototype.toString; var map = {'[objet booléen]': 'booléen', '[numéro d'objet]': 'numéro', '[string d'objet]': 'String', '[Fonction Object]': 'Function', '[Object Array]': 'Array', '[Object Date]': 'Date', '[Object Array " 'null', '[objet objet]': 'objet'}; if (obj instanceof element) {return 'élément'; } retour de la carte [toString.call (obj)];}D'autres façons?
Implémentation de jQuery
Pour plus de détails, veuillez consulter https: //github.com/jquery/jqu ...
Souligner la mise en œuvre
Pour plus de détails, veuillez consulter https: //github.com/jashkenas / ...
Mise en œuvre de Lodash
Pour plus de détails, veuillez consulter https: //github.com/lodash/lod ...
Implémentation JSON
Vous pouvez réaliser une copie profonde en passant d'abord JSON.Stringify, puis JSON.Parse. Cependant, le type de données prend en charge uniquement les types numériques de base.
var obj = {a: 'a', b: function () {console.log ('b')}} // Lorsque json.stringify, la fonction sera filtrée. Json.stringify (obj) // "{" a ":" a "}"résumé
Ici, nous résumons à peu près la copie profonde et comment implémenter une copie profonde. Dans différents scénarios, il est nécessaire de déterminer si une copie profonde est nécessaire en fonction du scénario commercial.