#javascript
#javascript
Вопрос:
Начальное понимание:
Я где-то читал, что когда ссылочные типы данных (объекты) присваиваются переменной A, переменная содержит адрес памяти объекта. И когда variableA присваивается variableB, variableB также получает копию этого адреса в памяти. Т.е. он ссылается на тот же объект. Мне понравилось это определение.
a = {color: "red"};
b = a;
//a = {color: "red"};
console.lo&(a);
console.lo&(b);
console.lo&(a === b);
Просмотр приведенного выше фрагмента подтверждает эту идею. Это выглядит как копия адреса памяти объекта, в a
котором хранятся ссылки a
. Когда a
присваивается b
, b
получает этот «адрес» и ссылается на тот же объект.
Однако это разваливается при a
повторной инициализации ( a = {color: "red"};
):
a = {color: "red"};
b = a;
a = {color: "red"};
console.lo&(a);
console.lo&(b);
console.lo&(a === b);
Я ожидал, что a === b
все равно вернется true
. Для меня это противоречит моему «первоначальному пониманию», потому что, конечно, если бы b
мне был присвоен тот же адрес в памяти, который a
является «меткой», b
он «обновился» бы и был меткой того же, что a
является меткой of .
Как мне пересмотреть свое понимание происходящего?
Комментарии:
1.
a = {color: "red"};
создает совершенно новый объект в правой части=
и присваиваетa
ссылку на этот совершенно новый объект. Новый объект явно не совпадает со старым объектом. Каждое выражение инициализатора объекта создает уникальный новый объект.2. @Pointy Взгляните на мое «потенциальное пересмотренное понимание». Я знаю, что новый объект
a
не совпадает со старым объектомa
. ( Я надеюсь, что это то, чтоa
означает быть «повторно инициализированным»!) Мой вопрос заключался в том,b
будет ли «догонять» и по-прежнему ли быть меткой того, чтоa
является меткой.3. вы сами это объяснили. b = a; копирует адрес памяти, а не объект. итак, когда вы создаете новый объект, он будет находиться в новой ячейке памяти.
4. @tonitone120 нет — присвоение
b
результатам не приводит к долговременной связи в между двумя переменными. Ссылка назначена, и все.5. Спасибо @Pointy, я думаю, что теперь это немного проясняется. Я был бы удовлетворен, если бы мог описать ситуацию следующим образом:
b = a
средствоb
сохраняет точный адрес в памяти, которыйa
был захвачен — в данный текущий момент . Между двумя переменными нет долгосрочной взаимосвязи.a
может быть повторно инициализирован и указывать на другую ячейку памяти; в то же время,b
все равно будет указывать на старую. Пока что-то ссылается на это старое местоположение, оно будет сохраняться.
Ответ №1:
Сначала вы создаете объект {color: "red"}
и устанавливаете на него ссылку из a
.
Чем вы позволяете b=a
, при этом ссылка из a копируется в b, поэтому обе ссылаются на один и тот же объект.
В-третьих, вы создаете совершенно новый объект {color: "red"}
и устанавливаете на него ссылку для a
. Итак, теперь у a есть новая ссылка на него, но у b все еще есть старая ..
Если вы сейчас сравните a===b
, будет проверено, идентичны ли ссылки, и это не так, так что это false.
Комментарии:
1. 1 для » ссылка скопирована «. Это не ссылка на
a
.
Ответ №2:
Из этой документации о равенстве объектов вы можете увидеть это:
Object.is()
определяет, являются ли два значения одним и тем же значением. Два значения одинаковы, если выполняется одно из следующих:
- оба не определены
- оба null
- оба истинны или оба ложны
- обе строки одинаковой длины с одинаковыми символами в одинаковом порядке
- оба объекта являются одними и теми же (означает, что оба объекта имеют одинаковую ссылку)
- оба числа и
- оба 0
- оба -0
- оба NaN
- или оба ненулевых, и оба не NaN, и оба имеют одинаковое значение
[…] Это также не то же самое, что быть равным в соответствии с оператором ===. Оператор === (а также оператор ==) обрабатывает числовые значения -0 и 0 как равные и обрабатывает число.NaN как не равный NaN
В случае, который вы опубликовали, выделенное условие не выполняется, поскольку новое назначение создает новый [сложный] объект: хотя значения между экземплярами одинаковы, их идентификаторы — нет.
Цель этой цитаты — проиллюстрировать сравнение объектов в JS различными способами, поскольку из вопросов ясно, что это ключевой момент, задаваемый пользователем.
Комментарии:
1. Просто чтобы уточнить: вы не используете напрямую
Object.is()
, но это иллюстрирует, как JS оценивает равенство объектов.2. в итоге вы на самом деле не хотите использовать == для определения того, похожи ли объекты.
3. Непонятно, почему вы цитируете документацию о том,
Object.is
когда используется OP===
?4. Я сказал в своем первом комментарии: чтобы проиллюстрировать равенство точек отсчета. В документации также разъясняются различия с
===
Ответ №3:
Когда вы пишете b = a
, вы заявляете, что можете вызывать a
object либо a
, либо b
. Другими словами, вы даете второе имя a
, то есть b
.
Если вы присваиваете a
новому объекту (открывая скобки с ключами {}
), a
это уже не тот объект, что b
, у них разные начала и идентификаторы.
Если вы хотите сравнить объекты по их содержимому, вы можете выполнить следующее:
var a = { color: 'red' };
var b = { color: 'red' };
console.lo&( JSON.strin&ify(a) );
console.lo&( JSON.strin&ify(b) );
Object.prototype.equals_obj = function(second) {
return JSON.strin&ify(this) == JSON.strin&ify(second);
}
console.lo&( a.equals_obj(b) );