102 votes

Comment l'assignation de variable fonctionne-t-elle en JavaScript?

J'ai donc été à jouer autour de l'autre jour, juste pour voir exactement comment la masse d'affectation fonctionne en JavaScript.

J'ai d'abord essayé cet exemple dans la console:

a = b = {};
a.foo = 'bar';
alert(b.foo);

Le résultat a été "bar" est affiché dans une alerte. C'est assez juste, a et b sont vraiment juste des alias pour le même objet. Puis j'ai pensé, comment pourrais-je faire de cet exemple simple.

a = b = 'foo';
a = 'bar';
alert(b);

C'est à peu près la même chose, n'est-ce pas? Eh bien cette fois, elle retourne foo pas bar que je m'attends à partir du comportement du premier exemple.

Pourquoi est-ce arrivé?

N. B. Cet exemple pourrait être simplifié encore plus avec le code suivant:

a = {};
b = a;
a.foo = 'bar';
alert(b.foo);

a = 'foo';
b = a;
a = 'bar';
alert(b);

(Je soupçonne que JavaScript traite primitives telles que des chaînes et des nombres entiers différemment pour les tables de hachage. Les hachages de retourner un pointeur alors que "de base" primitives retour une copie d'eux-mêmes)

118voto

Alex Wayne Points 58113

Dans le premier exemple, vous définissez une propriété d'un objet existant. Dans le deuxième exemple, l'affectation d'une nouvelle marque de l'objet.

a = b = {};

a et b sont maintenant des pointeurs vers le même objet. Ainsi, lorsque vous vous:

a.foo = 'bar';

Il définit b.foo depuis a et b pointent vers le même objet.

Toutefois!

Si vous faites ceci à la place:

a = 'bar';

vous dites que a de points à un objet différent maintenant. Cela n'a aucun effet sur ce que l' a a souligné avant.

En javascript, l'affectation d'une variable et l'attribution d'une propriété sont 2 opérations. Il est préférable de penser à des variables comme des pointeurs vers des objets, et quand vous attribuer directement à une variable, vous n'êtes pas modifier les objets, simplement de rejointoiement à votre variable d'un objet différent.

Mais l'affectation d'une propriété, comme a.foo, vont modifier l'objet qu' a de points à. Bien entendu, cela modifie également toutes les autres références qui pointent vers cet objet, simplement parce qu'ils pointent tous vers le même objet.

28voto

Christoph Points 64389

Votre question a déjà été répondu de manière satisfaisante par Squeegy - il n'a rien à voir avec les objets vs. des primitives, mais avec la réaffectation des variables vs la définition des propriétés dans le même objet référencé.

Il semble y avoir beaucoup de confusion à propos de JavaScript types dans les réponses et les commentaires, donc voici une petite introduction à JavaScript de type du système:

En JavaScript, il existe essentiellement deux types de valeurs: les primitives et les objets (et il n'y a pas de chose comme un 'hash').

Chaînes de caractères, les nombres et les booléens ainsi que null et undefined sont primitives, les objets sont tout ce qui peut avoir des propriétés. Même les tableaux et les fonctions sont des objets ordinaires et, par conséquent, peut contenir des propriétés arbitraires. Ils diffèrent juste à l'intérieur [[Catégorie]] propriété (fonctions disposent d'une propriété appelée [[]] et [[Construction]], mais bon, c'est des détails).

La raison que les valeurs primitives peuvent se comporter comme des objets, c'est à cause de l'autoboxing, mais les primitifs eux-mêmes ne peuvent pas contenir toutes les propriétés.

Voici un exemple:

var a = 'quux';
a.foo = 'bar';
document.writeln(a.foo);

Cela permettra de sortie undefined: a détient une valeur primitive, qui est promu à un objet lors de l'attribution de la propriété foo. Mais ce nouvel objet est immédiatement supprimé, de sorte que la valeur de foo est perdu.

Pensez-y comme ça:

var a = 'quux';
new String(a).foo = 'bar'; // we never save this new object anywhere!
document.writeln(new String(a).foo); // a completly new object gets created

4voto

Wimmer Points 752

Les hachages ou les tableaux sont considérés comme des "objets" en Javascript, d'où le comportement de référence.

Edit: Kevin m'a battu à cela.

3voto

Kevin Points 19613

Vous avez plus ou moins raison, sauf que ce que vous appelez un "hash" n'est en fait qu'une syntaxe abrégée pour un objet.

Dans le premier exemple, a et b font tous deux référence au même objet. Dans le deuxième exemple, vous modifiez a pour faire référence à quelque chose d'autre.

0voto

Nosredna Points 33670

La différence est entre les types simples et les objets.

Tout ce qui est un objet (comme un tableau ou une fonction) est passé par référence.

Tout ce qui est un type simple (comme une chaîne ou un nombre) est copié.

J'ai toujours une fonction copyArray à portée de la main afin que je puisse être sûr de ne pas créer un groupe d'alias dans le même tableau.

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