Vous entrez dans les détails de la vie quotidienne et je suis heureux que vous me le demandiez, car vous serez plus sage à la fin.
Ne le voyez pas en termes de pointeurs, car je pense que c'est là que vous vous trompez. Pensez-y plutôt en termes de tas (ou simplement de "mémoire" si vous voulez) et de table de symboles.
Commençons par prendre les premières lignes de votre code :
var a, b;
a = {}
b = a;
Ce que vous avez fait ici, c'est créer un objet sur le tas et deux symboles sur la table des symboles. Cela ressemble à quelque chose comme ça :
Tableau des symboles :
+--------+-----------------+
| Symbol | Memory Location |
+--------+-----------------+
| a | 0x400000 |
+--------+-----------------+
| b | 0x400000 |
+--------+-----------------+
Amas :
+----------+-----------------+
| Location | Value |
+----------+-----------------+
| 0x400000 | <object val 1> |
+----------+-----------------+
.
C'est là que les choses deviennent intéressantes : Les objets ont leurs propres "tables de symboles" (en général, il s'agit simplement de tables de hachage, mais le fait d'appeler cela une table de symboles peut rendre les choses plus claires).
Maintenant, après votre prochaine déclaration, vous avez 3 choses à prendre en compte : La table globale des symboles, <object val 1>
et le tas.
Exécutez la ligne suivante :
a['one'] = {}
Et maintenant les choses ressemblent à ça :
Tableau des symboles mondiaux :
+--------+-----------------+
| Symbol | Memory Location |
+--------+-----------------+
| a | 0x400000 |
+--------+-----------------+
| b | 0x400000 |
+--------+-----------------+
<object val 1>
Tableau des symboles de l'UE
+--------+-----------------+
| Symbol | Memory Location |
+--------+-----------------+
| one | 0x400004 |
+--------+-----------------+
Amas :
+----------+-----------------+
| Location | Value |
+----------+-----------------+
| 0x400000 | <object val 1> |
+----------+-----------------+
| 0x400004 | <object val 2> | <---we created a new object on the heap
+----------+-----------------+
.
Maintenant, vous avez exécuté le code suivant :
a = a['one'];
Cette modification devrait, nous l'espérons, sembler triviale. Le résultat est :
Tableau des symboles mondiaux :
+--------+-----------------+
| Symbol | Memory Location |
+--------+-----------------+
| a | 0x400004 |
+--------+-----------------+
| b | 0x400000 |
+--------+-----------------+
<object val 1>
Tableau des symboles de l'UE
+--------+-----------------+
| Symbol | Memory Location |
+--------+-----------------+
| one | 0x400004 |
+--------+-----------------+
Amas :
+----------+-----------------+
| Location | Value |
+----------+-----------------+
| 0x400000 | <object val 1> |
+----------+-----------------+
| 0x400004 | <object val 2> |
+----------+-----------------+
.
En suivant les emplacements de la mémoire jusqu'au tas, vous devriez comprendre pourquoi vous avez obtenu le résultat que vous avez obtenu.
Maintenant les choses deviennent encore plus intéressantes, parce que maintenant vous faites :
a['two'] = 2;
Ok, alors prenons ça étape par étape.
-
a
pointe vers l'emplacement mémoire 0x400004
qui contient <object val 2>
-
<object val 2>
est un objet vide, donc sa table de symboles commence par être vide.
- En exécutant cette ligne, nous ajoutons la variable 'deux' à
<object val 2>
de la table des symboles.
Si vous n'êtes pas encore fatigué de regarder ces diagrammes, vous le serez bientôt. Les choses ressemblent maintenant à ça :
Tableau des symboles mondiaux :
+--------+-----------------+
| Symbol | Memory Location |
+--------+-----------------+
| a | 0x400004 |
+--------+-----------------+
| b | 0x400000 |
+--------+-----------------+
<object val 1>
Tableau des symboles de l'UE
+--------+-----------------+
| Symbol | Memory Location |
+--------+-----------------+
| one | 0x400004 |
+--------+-----------------+
<object val 2>
Tableau des symboles de l'UE
+--------+-----------------+
| Symbol | Memory Location |
+--------+-----------------+
| two | 0x400008 |
+--------+-----------------+
Amas :
+----------+-----------------+
| Location | Value |
+----------+-----------------+
| 0x400000 | <object val 1> |
+----------+-----------------+
| 0x400004 | <object val 2> |
+----------+-----------------+
| 0x400008 | 2 (literal val) | <-- yes, even integers are stored on the heap
+----------+-----------------+ in JavaScript.
.
Si vous prenez le temps de suivre les emplacements de mémoire, vous verrez que votre navigateur a affiché la sortie correcte.