Подтвердить что ты не робот

Объект, скопированный во второе свойство через ссылку, сохраняется даже после удаления исходного свойства?

Я думал, что объекты передаются как ссылка. Но когда я удаляю b, он все еще существует в c. См. Этот пример:

Эта первая часть имеет смысл для меня, поскольку она передается по ссылке:

var a = {b: {val:true}};

a.c = a.b;
a.b.val = 'rawr';

console.log(uneval(a)); // outputs: "({b:{val:"rawr"}, c:{val:"rawr"}})"

Теперь эта часть не имеет для меня смысла:

var a = {b: {val:true}};

a.c = a.b;
a.b.val = 'rawr';
delete a.b;

console.log(uneval(a)); // outputs: "({c:{val:"rawr"}})"

поэтому свойство b удаляется, но свойство c содержит свойства, на которые ссылаются перед удалением. это ошибка в javascript?

изменить: спасибо всем ответам! поэтому это не ошибка, и это поведение на самом деле очень хорошо, это позволяет людям изменять имена "ключ" / "свойство" при сохранении объекта!:)

4b9b3361

Ответ 1

Нет, это не ошибка в JavaScript.

Что вы делаете с a.c = a.b, так это то, что вы создаете еще одну ссылку на один и тот же объект, что означает, что как a.b, так и a.c ссылаются на один и тот же под-объект {val: "rawr"}.

Когда вы выполняете delete a.b, вы не удаляете под-объект, вы удаляете только свойство a.b из a. Это означает, что a.c будет ссылаться на один и тот же объект.

Если вы также должны удалить свойство a.c, тогда под-объект будет исчезать.

Ответ 2

... Я опаздываю на вечеринку? Вот мое объяснение (прочитайте другие ответы, это просто, чтобы поддержать эти ответы с визуальным представлением):

  • Инициализация пустого объекта a другим объектом (value:true).

enter image description here

  1. Назначение пустого объекта a с помощью свойства b, относящегося к другому объекту (value:true).

enter image description here

  1. Назначение объекта a с помощью свойства c , ссылающегося на тот же объект (value:true).

enter image description here

  1. Удаление ключа b, поэтому a.b уже не ссылается на под-объект (value:true).

enter image description here

  1. Конечное представление основного объекта a.

enter image description here

Таким образом, мы можем легко увидеть наглядное представление о том, как сохранялся под-объект:)

Ответ 3

Следует отметить две вещи: во-первых, как сказано в других ответах, ключевое слово delete удаляет свойство только для объекта, через который вы переходите к доступу к свойству.

Второе, что нужно отметить, это то, что JavaScript не проходит по ссылке, никогда. Он всегда передается как значение, значения иногда ссылаются.

Например:

var a = {
   someObject: {}
};
var someObject = a.someObject;

someObject = 'Test';

console.log(a.someObject); // outputs {}

В языке, который проходит по ссылке, это, вероятно, вызовет ошибку, потому что это часто подразумевает сильную переборку переменных.

Ответ 4

Это потому, что:

Оператор delete удаляет свойство из объекта. Удаление MDN

Элемент b, который соответствует Object {val: true}, удаляется из a. Запись c в a все еще относится к этому объекту. Если вы попытаетесь удалить c.val или a.b.val, вы все равно увидите эффект каскадирования другого.

То, что вы пытаетесь сделать, то есть освобождение данных и ожидание их каскадирования, не происходит в javascript. Если у вас есть фон С++, подумайте о том, что все объекты javascript считаются ссылкой. Ican удалить ссылку на него (т.е. Запись, которая "указывает" на этот объект), но я не могу удалить сам объект. Это чистая прерогатива механизма javascript.

Ответ 5

С этой строкой вы думаете, что c указывает на b:

a.c = a.b;

но на самом деле оба c и b указывают на объект {val: true}, поэтому, если вы удаляете b, объект остается. вы можете просто подумать, что и c, и b являются просто "меткой", прикрепленной к объекту {val: true}

Ответ 6

Нет, это не ошибка.

Команда delete не удаляет объект, который ссылается на свойство, он удаляет только свойство. Если объект ссылается из другого места (другое свойство в этом случае), объект все еще жив.

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

var a = { val: true };
var b = a;
a = null;
console.log(b.val); // b still has a reference to the object