La copie d'un tableau d'objets à un autre Tableau, sans référence à l'objet en javascript(Deep copy)
J'ai un scénario où j'ai besoin de copier le tableau d'Objets(tableau Principal) à un autre Temp tableau qui ne devrait pas avoir un objet de référence, fondamentalement, si je fais toute modification du tableau Principal, il ne doit pas tenir compte, dans la Temp de la matrice de sorte que je vais conserver la copie de façon indépendante.
J'ai utilisé l'un de l'extrait de code de débordement de pile celui-ci n'est que partiellement comme si je supprime tous les objets du tableau Principal de la temp de la matrice de toujours conserver la valeur, mais quand je fais quelques modifications dans le tableau principal et cliquez sur le bouton annuler iam retrait de tous les objets du tableau principal à l'aide du tableau.Removeall(); mais la modification existent encore en Temp tableau donc, ce qui signifie que les objets ayant une référence.
clone: function (existingArray) {
var newObj = (existingArray instanceof Array) ? [] : {};
console.debug('newObj value is ' + newObj);
for (i in existingArray) {
console.debug('i value is' + i);
if (i == 'clone') continue;
console.debug('existingArray[i] value ' + existingArray[i]);
if (existingArray[i] && typeof existingArray[i] == "object") {
newObj[i] = this.clone(existingArray[i]);
} else {
console.debug('in else part ' + existingArray[i]);
newObj[i] = existingArray[i];
}
}
return newObj;
}
ma structure de l'objet, c'est comme
iam à l'aide de knock-out cadre.
newObjectCreation = function (localIp, RemoteIp, areaId) {
this.localIP = ko.observable(localIp);
this.remoteIP = ko.observable(RemoteIp);
this.areaId = ko.observable(areaId);
};
template.ProtocolArray.push(new newObjectCreation('', '', '')); //to create default row
s'il vous plaît aidez-moi à cet égard.
Merci à l'avance.
- Faire de les objets contiennent rien qui n'est pas exprimable comme JSON (pas littéral d'objet)? Si non, vous pourriez faire simple:
var clone = JSON.parse(JSON.stringify(src));
- Connexes: stackoverflow.com/questions/122102/...
- Double Possible de la Copie de tableau par valeur en JavaScript
Vous devez vous connecter pour publier un commentaire.
Permettez-moi de comprendre: vous ne voulez pas juste un nouveau tableau, mais vous souhaitez créer une nouvelle instance pour tous les objets sont présents dans le tableau lui-même? Donc, si vous modifiez l'un des objets dans le temp tableau, qui change, c'est pas propagé dans le tableau principal?
Si c'est le cas, ça dépend par les valeurs que vous conservez dans le tableau principal. Si ces objets sont des objets simples, et ils peuvent être sérialisés en JSON, puis le moyen le plus rapide est:
Si vous avez des objets plus complexes (comme les instances créées par certains de vos propres constructeurs, html nœuds, etc), alors vous avez besoin d'une approche ad hoc.
Edit:
Si vous n'avez pas toutes les méthodes sur votre
newObjectCreation
, vous pouvez utiliserJSON
, cependant, le constructeur ne sera pas le même. Sinon, vous avez à faire le copier manuellement:function foo(a) { this.a = a }; var main = [new foo(1)], temp = JSON.parse(JSON.stringify(main));
alors vous aurezmain[0].a
est égal à1
ettemp[0].a
ainsi. Si vous modifiez la dernièretemp[0].a = 4
que les modifications ne sont pas répercutées àmain[0].a
. Cependantmain[0].constructor
estfoo
ettemp[0].constructor
estObject
.function cloneObject (o) { return JSON.parse(JSON.stringify(o)); }
...sauf à faire quelque chose de plus rapide derrière-le-scènes. Ou encore mieux: une méthode pour tous les objets appelésclone()
si vous pouviez juste fairemainArray.clone()
.Lodash peut être utilisé pour la profondeur de la copie d'objets _.cloneDeep(valeur)
Si vous voulez une copie en profondeur sans la référence d'objet? Bien sûr, l'utilisation
.slice()
.Exemple:
PS: je ne pense pas que le double-parsing JSON est performance sage.
[[4,2,6,5],[1,8,7,3]]
. Dans ce cas, vous pouvez effectuer les opérations suivantes:var start = [[4,2,6,5],[1,8,7,3]]; var temp = start.map(e => e.slice(0))
Pour certains d'autres personnes avec la même question. Vous pouvez aussi le faire de cette façon.
À l'aide de la nouvelle es6 caractéristiques vous pouvez créer une copie d'un tableau (sans référence) et une copie de chaque objet, sans un niveau de références.
C'est beaucoup plus fonctionnelle et idiomatiques à mon humble avis
Donc, fondamentalement, si vos objets n'ont pas des objets comme des propriétés. Cette syntaxe est tout ce dont vous avez besoin. Malheureusement, il n'est pas "out of the box" de profondeur en fonction de clonage sur les spec mais vous pouvez toujours utiliser une bibliothèque si c'est ce que vous avez besoin
La Compatibilité du navigateur Avertissement: je pense que c'est une partie de la spécification Ecma maintenant, mais certains navigateurs n'ont pas une pleine soutien de la propagation de la syntaxe de jet. Mais à l'aide de l'un des populaires transpilers là, vous serez bien
Pour copier les valeurs d'un tableau sans copier la référence de la matrice, vous pouvez tout simplement faire:
C'est la solution recommandée pour AirBnb JS Guide de Style: https://github.com/airbnb/javascript#arrays
Toutefois, cela ne créera pas de nouveaux referenes pour les objets à l'intérieur de la matrice. Pour créer une nouvelle référence pour le tableau et les objets à l'intérieur, vous pouvez faire:
var start = [[4,2,6,5],[1,8,7,3]]; var temp = start.map(e => e.slice(0)); var tempEs6 = start.map(e => [...e]);
Vous pouvez utiliser Angulaire de la copie:
angular.copy();
Utilisation
angular.copy
. Mais pas pour l'ensemble du tableau (car elle permettrait de passer des éléments de tableau de référence), mais de le parcourir et d'utiliserangular.copy
sur ses membres.