2010-07-15 7 views
1

Je ne suis pas très sûr du titre de la question, est la situation ici, s'il vous plaît voir le code exemple suivantjavascript valeur de la propriété objet conflit

// original data 
a = [ 
    {x : 1}, 
    {x : 2}, 
    {x : 3} 
] 

// assign to a variable 
b = a[0] 

// do some change 
b.x = 5 

alert(a[0].x) 
// i thought it would still be 1 but it is 5, why??? 

* modifier
merci Ambre et Andrei
i pense que je vais juste écrire une fonction pour faire défiler les propriétés de l'objet pour copier vers un nouvel objet
merci encore pour l'aide :)

+0

Vous devriez jeter un coup d'œil à http://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-clone-a-javascript-object pour des suggestions sur la façon de procéder. –

Répondre

1

Objets sont attribués par référence - ce qui signifie que lorsque vous modifiez quoi que ce soit t référence l'objet, il le modifie dans tous les cas où il est référencé.

b est simplement de stocker une référence au même objet que a[0] stocke une référence à.

+0

est-il possible d'éviter cela? ou chaque fois que je veux modifier une propriété d'objet je dois le stocker dans une autre variable? – ben

+0

alors si j'ai besoin de copier les données stockées dans un autre obj sans référence à un? – ben

+0

Vous devez faire ce qu'on appelle une «copie profonde» - http://snipplr.com/view/15407/deep-copy-an-array-or-object/ – Amber

0

Pensez-y de cette façon. a[0] n'est pas l'objet réel {x : 1}. Cet objet se trouve quelque part en mémoire et a[0] contient l'adresse mémoire où cet objet est stocké.

Si vous faites a[0].x, vous le déréférenciez. Cela signifie que vous analysez la pièce avant le . et voyez l'adresse. Vous allez alors chercher l'objet à cette adresse et voir s'il a une propriété x et le renvoyer. Mais si vous faites b=a[0], vous copiez simplement l'adresse de l'objet en b. Donc maintenant vous avez deux références (raccourcis vers l'adresse mémoire où l'objet est stocké). Si vous faites maintenant b.x = 5 vous regardez ce qui est avant le .; c'est b contenant l'adresse de l'objet, vous récupérez cet objet de la mémoire, vérifiez s'il a la propriété x et changez sa valeur à 5. Mais a[0] points à la même adresse (donc sur le même objet) donc si vous essayez de faire a[0].x Comme avant, vous arrivez à l'adresse que vous venez de modifier.

Il s'agit d'une explication simplifiée, mais vous devez penser aux variables qui contiennent des objets en tant que raccourcis vers l'adresse mémoire où se trouve l'objet réel. Et si vous essayez d'attribuer à une variable la valeur d'une autre variable d'objet, vous venez de créer un nouveau raccourci. Cela n'est pas vrai pour les variables contenant des nombres, donc x contient en réalité la valeur 1, ou 5, pas une adresse. Donc, si vous faites:

y = a[0].x; 
y = 10; 

a[0].x ne changera pas sa valeur.

+0

merci Andrei :) Je suppose que cela signifie que je ne peux pas il suffit de copier un arbre while d'un noeud d'objet à un autre objet, je vais devoir assigner les valeurs une par une :( – ben

Questions connexes