Вы можете использовать linq для сравнения ключей и значений:
public bool Compare & lt; TKey, TValue & gt; (Dictionary & lt; TKey, TValue & gt; dict1, Dictionary & lt; TKey, TValue dict2) {IEqualityComparer & lt; ; TValue & GT; valueComparer = EqualityComparer & lt; TValue & gt; .Default; return dict1.Count == dict2.Count & amp; & amp; & amp; dict1.Keys.All (key = & gt; dict2.ContainsKey (key) & amp; valueComparer.Equals (dict1 [key], dict2 [key])); }
Следуя вашему примеру, строка за строкой:
a = {}
a
теперь ссылается на новый объект.
b = a;
b
теперь ссылается на тот же объект, что a
Рекомендации. Обратите внимание, что это не ссылается на a
.
a['one'] = {};
Новый объект теперь имеет индекс 'one'
, который ссылается на другой новый объект.
Когда вы делаете
a = a['one'];
Вы устанавливаете a
для обозначения a['one']
, который является тем новым созданным вами объектом, когда вы делали a['one'] = {}
. b
по-прежнему ссылается на объект, созданный с помощью a = {}
.
Вы путаете проблему, когда говорите: «a
потерял ссылку на b
», потому что a
не ссылается на b
, и наоборот. a
и b
относятся к объектам , и их можно заставить ссылаться на другие объекты. Например:
С помощью a = {}; b = a
вы получаете
a
\
\
{ }
/
/
b
Затем с a['one'] = {}
вы получаете
a
\
\
{ one: { } }
/
/
b
Затем с помощью a = a['one']
вы get
a - - - -
\
{ one: { } }
/
/
b
Объекты в Javascript могут существовать сами по себе, не нуждаясь в имени. Например:
{}
- новый экземпляр словарного объекта.
a = {};
создает новый объект словаря и ссылается на a
. Теперь
b = a;
делает b
ссылкой на один и тот же базовый объект. Затем вы можете сделать точку a
в другом месте:
a = "hi";
и b
все еще указывает на тот же словарь, что и раньше. Поведение b
не связано с тем, как вы изменяете то, что указывает a
.
Подумайте об анонимном объекте, поскольку он сам имеет имя:
a = {}; // The variable "a" now points to (holds) an anonymous object.
b = a; // "b" points to the same anonymous object held by "a".
a = 123; // "a" now holds some other value.
b; // "b" still holds the anonymous object.
Ключ должен помнить, что переменные содержат ссылки на objects , а не ссылки на другие переменные. И тот же объект может ссылаться на любое количество переменных.
Насколько я знаю, вы перезаписали, поэтому я думаю, что двигатель сохраняет его в другом пространстве памяти, тогда как b все еще указывает на адрес памяти старого a (который каким-то образом не разрушается).
: P Ты спускаешься в мельчайшие детали, и я рад, что ты спросил, как ты будешь мудрее к концу.
Не смотрите на это с точки зрения указателей, потому что Я думаю, это то, где вы запутались. Подумайте об этом скорее с точки зрения кучи (или просто «памяти», если хотите) и таблицы символов.
Давайте начнем с ввода первых нескольких строк вашего кода:
var a, b;
a = {}
b = a;
Вы сделали здесь один объект в куче и два символа в таблице символов. Это выглядит примерно так:
Таблица символов :
+--------+-----------------+
| Symbol | Memory Location |
+--------+-----------------+
| a | 0x400000 |
+--------+-----------------+
| b | 0x400000 |
+--------+-----------------+
Куча :
+----------+-----------------+
| Location | Value |
+----------+-----------------+
| 0x400000 | <object val 1> |
+----------+-----------------+
.
Здесь интересны вещи: у объектов есть свои «таблички символов» (обычно это просто хеш-таблицы, но называть их таблицей символов можно сделать более ясным).
Теперь, после вашего следующего утверждения, у вас есть 3 вещи: таблица глобального символа, таблица символов <object val 1>
и куча.
Запустите следующую строку:
a['one'] = {}
И теперь все выглядит так:
Глобальная таблица символов :
+--------+-----------------+
| Symbol | Memory Location |
+--------+-----------------+
| a | 0x400000 |
+--------+-----------------+
| b | 0x400000 |
+--------+-----------------+
<object val 1>
Таблица символов
+--------+-----------------+
| Symbol | Memory Location |
+--------+-----------------+
| one | 0x400004 |
+--------+-----------------+
Куча :
+----------+-----------------+
| Location | Value |
+----------+-----------------+
| 0x400000 | <object val 1> |
+----------+-----------------+
| 0x400004 | <object val 2> | <---we created a new object on the heap
+----------+-----------------+
.
Теперь вы выполнили следующий код:
a = a['one'];
Это, должно быть, кажется тривиальным изменением. Результат:
Таблица глобальных символов :
+--------+-----------------+
| Symbol | Memory Location |
+--------+-----------------+
| a | 0x400004 |
+--------+-----------------+
| b | 0x400000 |
+--------+-----------------+
Символьная таблица <object val 1>
+--------+-----------------+
| Symbol | Memory Location |
+--------+-----------------+
| one | 0x400004 |
+--------+-----------------+
Куча :
+----------+-----------------+
| Location | Value |
+----------+-----------------+
| 0x400000 | <object val 1> |
+----------+-----------------+
| 0x400004 | <object val 2> |
+----------+-----------------+
.
Следуя ячейкам памяти в куче, мы, надеюсь, сделаем это ясно, почему вы получили результат, который вы сделали.
Теперь все становится еще интереснее, потому что теперь вы делаете:
a['two'] = 2;
Хорошо, давайте сделаем это шаг за шагом.
a
указывает на ячейку памяти 0x400004
, которая содержит <object val 2>
<object val 2>
- пустой объект, поэтому его таблица символов начинает пуст <object val 2>
. Если вы еще не устали смотреть на эти диаграммы, вы будете быть. Теперь все выглядит так:
Таблица глобальных символов :
+--------+-----------------+
| Symbol | Memory Location |
+--------+-----------------+
| a | 0x400004 |
+--------+-----------------+
| b | 0x400000 |
+--------+-----------------+
Символьная таблица <object val 1>
+--------+-----------------+
| Symbol | Memory Location |
+--------+-----------------+
| one | 0x400004 |
+--------+-----------------+
<object val 2>
Символьная таблица
+--------+-----------------+
| Symbol | Memory Location |
+--------+-----------------+
| two | 0x400008 |
+--------+-----------------+
Куча :
+----------+-----------------+
| Location | Value |
+----------+-----------------+
| 0x400000 | <object val 1> |
+----------+-----------------+
| 0x400004 | <object val 2> |
+----------+-----------------+
| 0x400008 | 2 (literal val) | <-- yes, even integers are stored on the heap
+----------+-----------------+ in JavaScript.
.
Если вы усердно занимаете время, чтобы следить за местоположениями памяти, вы увидите, что ваш браузер отобразил правильный вывод.