Объекты JavaScript с перекрестными ссылками

Прочитайте комментарии в коде ниже, чтобы узнать, что я пытаюсь спросить.

Ожидаемый результат: В соответствии с механизмом посредника в JavaScript, objOne ожидается в журнале {} в конце, потому что objTwo был инициализирован {}.

var objOne = {
  x: 1,
  y: 2
};

var objTwo = objOne;

// change the x vlaue to 2 by objTwo
objTwo.x = 2;

// Change the value of key x in objOne as well - pass by reference mechanism
console.log(objOne); // { x: 2, y: 2 }

/*** Pass by reference is understood in code, above this comment ***/

// Now what if objTwo initialized with empty object
objTwo = {};

console.log(objOne); // { x: 2, y: 2 } but expected output = {}

// As per pass by reference mechanism. objOne is expected to log {}, because objTwo was initialized with {}.

Ответ 1

Когда вы назначаете одну переменную другой, это не означает, что обе эти переменные теперь связаны ссылкой; вы понимаете, что означает "передать по ссылке" здесь.

Переменная, удерживающая объект, не "непосредственно" удерживает объект. То, что оно содержит, является ссылкой на объект. Когда вы назначаете эту ссылку из одной переменной в другую, вы делаете копию этой ссылки. Теперь обе переменные содержат ссылку на объект. Изменение объекта через эту ссылку изменяет его для обеих переменных, содержащих ссылку на этот объект.

Когда вы назначаете новое значение одной из переменных, вы просто изменяете значение, которое имеет переменная. Теперь переменная перестает удерживать ссылку на объект и вместо этого содержит что-то еще. Другая переменная по-прежнему содержит ссылку на исходный объект, присваивание вообще не повлияло на нее.

Ответ 2

Когда вы оцениваете

objTwo = {};

Javascript интерпретирует это как переназначение objTwo на новый литерал пустой объект и оставляет только его старое значение.

Если вы хотите удалить ключ из objOne по ссылке, вы можете использовать ключевое слово delete:

delete objTwo.x;  // also deletes the x property of objOne

Ответ 3

Когда 2 переменные указывают на один и тот же объект, это не означает, что они теперь магически "связаны" друг с другом.

В вашем случае objTwo = {} просто меняет objTwo, чтобы указать на новый созданный вами объект.

Ответ 4

objTwo = {}; работает не так, как вы думаете. Обычно я рекомендую рассматривать переменные как "указатели".

objOne и objTwo - две совершенно разные переменные. Когда вы выполнили objTwo = {};, то, что он сделал, это указать переменную objTwo на другой объект. Он не изменяет переменную objOne.

Представьте себе:

var objOne = {
  x: 1,
  y: 2
};

// objOne -> { x: 1, y: 2 }

var objTwo = objOne;

// objOne -> { x: 1, y: 2 } <- objTwo

objTwo.x = 2;

// objOne -> { x: 2, y: 2 } <- objTwo (update object via objTwo variable)

objTwo = {};

// objOne -> { x: 2, y: 2 }, objTwo -> {}

Ответ 5

Пропуск JavaScript по ссылке отличается, ваш объект рассматривается как ссылка, если вы меняете его атрибуты, такие как obj.x = 1, но назначение самой переменной объекта (obj = []) будет относиться к ней как к переменная, основанная на значении.

Ответ 6

только удаление может вызвать состояние инициализации.

for(var i in objOne){
    delete objOne[i];
}

@nrabinowitz говорит

  • Javascript всегда проходит по значению, но когда переменная ссылается на объект (включая массивы), "значение" является ссылкой на объект.
  • Изменение значения переменной никогда не изменяет базовый примитив или объект, оно просто указывает переменную на новый примитив или объект.
  • Однако изменение свойства объекта, на которое ссылается переменная, изменяет базовый объект.

Ответ 7

Я согласен с принятым ответом, это всего лишь некоторый код для его подтверждения.

let objOne = {x: 1, y: 2};
let objTwo = objOne; // referencing to same thing

objTwo.x = 2;
console.log(objOne, objTwo); // output {x:2, y:2}, {x:2, y:2}

let objThree = {};
objTwo = objThree; // notice this. Same as "objTwo = {}", except now you have objThree as initial reference
console.log(objOne, objTwo, objThree); // output {x:2, y:2}, {}, {}

Вы можете легко заметить, что произошло, изменив ссылку на objTwo или добавив в нее новое значение, как показано в примере с вопросом.

Ответ 8

Вот как работает переход по ссылке. Здесь objTwo относится к objOne, поэтому все, что вы делаете с objTwo, будет происходить и с objOne.