495 votes

Comment cloner un tableau d'objets en Javascript

...où chaque objet ont également des références à d'autres objets dans le même tableau? Quand je suis venu avec ce problème je viens bien de quelque chose comme

var clonedNodesArray = nodesArray.clone()

serait il existe et cherché des infos sur comment le clonage des objets en javascript. J'ai trouvé une question sur StackOverflow (répondu par le même John Resig) et il a souligné qu'avec jQuery, vous pourriez faire

var clonedNodesArray = jQuery.extend({}, nodesArray);

pour cloner un objet. J'ai essayé cette même, cette copie uniquement les références des objets dans le tableau. Donc, si je

nodesArray[0].value = "red"
clonedNodesArray[0].value = "green"

la valeur des deux nodesArray[0] et clonedNodesArray[0] à son tour d'être "vert". Ensuite, j'ai essayé

var clonedNodesArray = jQuery.extend(true, {}, nodesArray);

lequel des copies d'un Objet, mais j'ai eu "trop de récursivité" et "contrôle de débordement de pile" les messages des deux Firebug et Opera Dragonfly respectivement.

Comment le feriez-vous? Est-ce quelque chose qui ne devrait même pas être fait? Est-il réutilisable façon de le faire en javascript?

612voto

Allez les gars, c'est le 21ème siècle, pas besoin de boucles pour cloner des tableaux et des objets. Solution pure vanille une ligne

 var clonedArray = JSON.parse(JSON.stringify(nodesArray))
 

157voto

Leopd Points 12652

Si tout ce dont vous avez besoin est une copie superficielle, la méthode la plus simple est la suivante:

 new_array = old_array.slice(0);
 

118voto

Daniel Lew Points 39063

De la question avec votre copie superficielle, c'est que tous les objets ne sont pas dupliqués. Alors que les références à chaque objet sont uniques dans chaque tableau, une fois que vous avez finalement s'accrocher à elle, vous avez à traiter avec le même objet comme avant. Il n'y a rien de mal avec la façon dont vous cloné... le même résultat est obtenu à l'aide du Tableau.slice().

La raison de votre copie en profondeur est d'avoir des problèmes c'est que vous êtes en terminant par circulaire les références de l'objet. Profondeur vais aller aussi profondément que possible, et si vous avez un cercle, il va continuer à l'infini jusqu'à ce que le navigateur s'évanouit.

Si la structure de données ne peut pas être représenté comme un graphe dirigé acyclique, alors je ne suis pas sûr que vous allez être en mesure de trouver une méthode pour la profondeur de clonage. Cyclique des graphiques fournissent de nombreux délicat coin des cas, et puisque ce n'est pas une opération courante, je doute que quiconque a rédigé une solution complète (si c'est encore possible - c'est peut-être pas! Mais je n'ai pas de temps à essayer d'écrire une preuve rigoureuse maintenant.). J'ai trouvé quelques bons commentaires sur la question sur cette page.

Si vous avez besoin d'une copie d'un Tableau d'Objets avec des références circulaires, je crois que vous allez avoir votre propre code de méthode pour gérer votre spécialisées, structure de données, tel que c'est le multi-pass clone:

  1. Sur un tour, faire un clone de tous les objets ne faisant pas référence à d'autres objets dans le tableau. Garder une trace de chaque objet origines.
  2. Sur la deuxième ronde, de lier les objets entre eux.

30voto

SET Points 2729

Clonez simplement n'importe quel type de tableau avec:

 [].concat(data);
 

ou, puisque concat peut ne pas fonctionner dans certains navigateurs IE, vous pouvez utiliser ceci:

 data.slice(0);
 

18voto

elsereturn Points 193
$.evalJSON($.toJSON(origArray));

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X