2017-08-21 4 views
-2

J'ai utilisé JavaScript pendant des années et celui-ci m'a perplexe. Comme je l'ai compris les choses, lors de la définition d'un var, l'une des deux choses:javascript primitives vs références d'objet

  1. Si l'expression est une primitive, var est définie comme une nouvelle instance de cette primitive sans référence à l'expression passée.
  2. Si l'expression est un littéral d'objet, un nouvel objet est créé.
  3. Si l'expression est un objet existant, var fera référence à l'objet et toutes les modifications futures de l'objet seront reflétées.

Cependant, j'ai couru dans une situation où le cas 3 ne s'applique pas:

var obj = {body: {'a': 1, 'b': 2, 'c': 3}}; 

var ref = obj.body; 
ref = JSON.stringify(ref); 

console.log(typeof ref); // string 
console.log(typeof obj.body); // object 

Depuis ref est définie comme la propriété body de obj, je pensais redéfinir ref comme une chaîne aussi serait affecter obj.body. Alors qu'est-ce qui me manque?

+1

vous remplacez la variable, ça ne va pas changer ce qui est dans l'objet .... – epascarello

+0

Je pense que la confusion vient du fait que 'ref = ...' ne mute pas l'objet vers lequel il pointe. Si vous avez muté 'ref' (en définissant' ref.a = 5' par exemple), vous verrez les mises à jour via les deux références. – Phylogenesis

Répondre

0

Les primitives sont immuables. S'il y a une différence dans la façon dont ils se comporteraient par rapport aux objets, vous ne pouvez pas l'observer, alors oubliez tout ce qui concerne la copie. Parlons plutôt en termes de "choses"! Les objets et les primitives sont deux choses. Lorsque vous affectez une chose à une variable, vous ne copiez pas la chose.

var x = literally any value; 
var y = x; 

x et y sont les deux variables qui contiennent la même chose. Si vous changez la chose, peu importe où vous y accédez à l'avenir; la chose a changé. Si vous changez la chose que la variable contient, la chose qu'elle contenait n'est pas affectée.

var z = some other value; 
y = z; // y now contains the same thing as z instead of the same thing as x 
     // only variables changed, and the things did not 

Il y a beaucoup de réponses qui en parlent en d'autres termes mais j'aime le langage technique.

tl; dr: Pour toutes fins utiles, la distinction entre les objets et les primitives dans JavaScript n'est pas utile.

ts; iwrse: This article about Python s'applique tout autant à JavaScript.

+0

long formulaire commentaires ftw – Ryan

2

JSON.stringify est une méthode qui prend un objet et renvoie sa représentation sous forme de chaîne, elle ne change rien. En faisant ref = x vous faites ref point à une autre chose, cela n'affecte pas ce qui était là avant l'affectation.

+0

Je suis toujours confus.Si 'ref' fait référence à' obj.body', et ensuite 'ref = 'foo'', est-ce que obj.body ne serait pas redéfini comme' 'foo''? – Cliff

+1

@Cliff en faisant 'ref = 'abc'' vous faites pointer' ref' vers un objet complètement nouveau. –

+0

@Cliff Envisager d'accepter la réponse s'il vous plaît –

0

Cela signifie simplement que vous ne faites plus référence à obj.body .body et que vous faites référence à autre chose.

var ref = obj.body; 

//ref holding obj.body now any changes to ref will effect obj.body. 

ref = JSON.stringify(ref); 

//ref holding a String returned by `stringify()` now any changes to ref will effect obj.body. 

Vous voyez ?? Vous venez de changer le ref avec des valeurs différentes. Pas vraiment changer quoi que ce soit sur obj