Если у двух массивов есть элемент, который указывает на (ссылки) один и тот же объект, и вы меняете объект через один массив, он изменяется в другом массиве, как я доказал себе в первом фрагменте ниже.Если два массива JavaScript объектов разделяют элементы, является ли сборщик мусора, не связанный с общей памятью, когда один массив больше не ссылается?
Мой вопрос в том, что если массив a1 указан в другом коде, например обработчик события, а a2 не упоминается нигде и не выходит за пределы области видимости, тогда все «крупные» браузеры мусора собирают память, используемую сам массив a2, включая указатели на объекты, и память для объекта, созданного во втором нажатии в фрагменте ниже. Если это так, то, поскольку a2 больше не имеет указателей на объекты в a1, то, если a1, наконец, выходит из области видимости, тогда вся связанная с ним память, включая все объекты, на которую она указывает, будет исправлена GC, не предполагая никаких других указателей , кроме тех, которые связаны с a1 и a2, ссылаются на эти объекты?
Я знаю, что это академический пример для этого простого примера, но я пишу алгоритм (см. Второй фрагмент), чтобы сделать вложенный объект из сплющенной версии тех же данных в массиве, и при этом я использую временную массив, который содержит элементы, указывающие на каждый объект в исходном массиве. Я планирую назвать это неопределенным количеством раз, и я хочу убедиться, что я не утечка памяти. В массиве будет больше элементов, чем в фрагменте.
Я также знаю, что есть другие вопросы, которые имеют сильное сходство с этим, и ответы были полезны, но я не думаю, что кто-то окончательно ответил на каждую часть.
var a1 = [{first: 1, second: 2}, {first: 4, second: 2}, {first: 3, second: 4}];
var a2 = [a1[2]];
a2.push(a1[1]);
a2.push({first: 5, second: 8});
console.log('a1 = ' + JSON.stringify(a1, null));
console.log('a2 = ' + JSON.stringify(a2, null));
a2[0].first = 7;
a2[1].second = 9;
console.log('a1 = ' + JSON.stringify(a1, null));
console.log('a2 = ' + JSON.stringify(a2, null));
var events = [
{
"id": 7,
"parentId": 4,
"name": "Sub7",
"expected": 400,
"actual": 100
},
{
"id": 2,
"parentId": 1,
"name": "Sub2",
"expected": 200,
"actual": 100
},
{
"id": 4,
"parentId": 1,
"name": "Sub4",
"expected": null,
"actual": 100
},
{
"id": 8,
"parentId": 1,
"name": "Sub8",
"expected": 250,
"actual": 100
},
{
"id": 1,
"parentId": null,
"name": "Main",
"expected": null,
"actual": 100
},
{
"id": 6,
"parentId": 4,
"name": "Sub6",
"expected": 300,
"actual": 100
}
];
var temp = [];
var parent;
for (var i = 0; i < events.length; i++) {
if (temp[events[i].id]) {
Object.assign(temp[events[i].id], events[i]);
} else {
temp[events[i].id] = events[i];
temp[events[i].id].children = [];
}
var parentId = events[i].parentId;
if (!parentId) {
parent = temp[events[i].id];
} else {
if (!temp[parentId]) {
temp[parentId] = {
id: parentId,
parentId: undefined,
name: undefined,
expected: undefined,
actual: undefined,
children: [temp[events[i].id]]
}
} else {
temp[parentId].children.push(temp[events[i].id]);
}
}
delete temp[events[i].id].parentId;
}
temp = undefined;
document.write('<code><pre>' + JSON.stringify(parent, null, 2) + '</pre></code>');
Эта страница Mozilla, с которой вы связались, и фразы на нем, такие как «mark and sweep», которые привели меня к другим источникам информации, оставили меня достаточно уверенным в том, что мне не нужно беспокоиться об использовании временного массива в моем примере, хотя он будет использоваться много раз для многих элементов. –
Правильно. Лучшим советом является сохранение ваших объявлений в минимальном объеме, который вы можете, так что, когда функции заканчиваются, собираются локальные переменные. –