О, мальчик, вы поймали один из текущих и наиболее очевидных недостатков JavaScript, эффективно используя это:
clubs[i].event[j].clubInfo = clubs[i];
Вы создаете бесконечную ссылку - что я имею в виду под этим? Лучше показывать через массив, если вы мне навязываете:
let a=[]; a.push([a]);
Это создает массив бесконечного уровня посредством самообращения, создавая неисчислимую глубину. Видите ли, хотя есть ограничение в 32 (2 ^ 32-1) для длины массива. Это можно легко продемонстрировать:
Array(2**32); //Uncaught RangeError: Invalid array length
Предположительно, это было сделано для предотвращения укорачивания памяти браузера, но, как ни странно, никогда не учитывалось, какую глубину может содержать массив. Небольшим побочным эффектом этого является то, что отсутствует свойство depth
, но основным побочным эффектом является отсутствие защиты от бесконечного массива самоссылки .
Обойти это
Лучший способ обойти ситуацию такого типа - создать новый объект и присвоить свойства старого объекта новому. Вы можете думать об этом как клонирование . Для этого вы можете использовать метод assign
:
Object.assign(constructor, **Array**/**Object**)
* 1 028 * Пример:
let a = []; a.push(Object.assign([], a));
Проблема решена, верно? э-э-э ... не совсем Несмотря на то, что иногда это может работать, это все равно не решит проблему Массива или Объекта с большим , чем поверхностные ссылки. Чтобы обойти это, вы должны использовать комбинацию:
JSON.stringify(obj);
до прервать ссылки
JSON.parse(JSON);
до переделать ваш объект и
delete obj[deepReference];
удаление , чтобы остановить любые непредвиденные проблемы с любыми лишними данными / ссылками
Ничего из этого не является идеальным, но в настоящее время нет способа полностью отделить все ссылки внутри объекта или массива без рекурсивной итерации.
В качестве примера - В вашем случае вы захотите сделать что-то вроде этого:
for (var i = 0; i < clubs.length; i++) {
var clubInfo = clubs[i];
var events = clubs[i].events;
for (var j = 0; j < events.length; j++) {
let jsonTranslation = Object.assign({}, clubs[i]);
delete jsonTranslation.events;
jsonTranslation = JSON.stringify(jsonTranslation);
clubs[i].events[j].clubInfo = JSON.parse(jsonTranslation);
}
}
let clubs = [{
propA: "blah",
probB: "bar",
events: [{
data1: "foo",
data2: "bar"
},
{
data1: "this",
data2: "that"
}
]
}];
for (var i = 0; i < clubs.length; i++) {
var clubInfo = clubs[i];
var events = clubs[i].events;
for (var j = 0; j < events.length; j++) {
let jsonTranslation = Object.assign({}, clubs[i]);
delete jsonTranslation.events;
jsonTranslation = JSON.stringify(jsonTranslation);
clubs[i].events[j].clubInfo = JSON.parse(jsonTranslation);
}
}
console.log(clubs);
Дополнительная информация: Другие часы наблюдения
Точно так же есть другие проблемы в языке. Плохо реализованный метод конструктора Array. Array(n)
возвращает массив с n
членами. Почему это проблема? Все в JavaScript, которое объявлено и не создано, является undefined
, кроме членов только что созданного массива. Они возвращают пусто . Проблема в том, что у них нет сопоставляемых значений. Следовательно, все эти приятные новые функциональные методы ES Array бесполезны, пока Array не заполнится. Как пример:
Array(3).map((m, i) => i);
В результате получается хорошо ... то же самое, с чего вы начали - когда ясно, что он должен обеспечивать нумерованный массив от 0 до 2. Это не так важно, как бесконечная ссылка , потому что вы можете обойти это следующим образом:
Array(3).fill(0).map((m,i) => i);
Но это фактически пустой метод, который решает проблему, которая должна быть решена внутри конструкции.
Наконец, метод fill
- дайте ему объект или массив, и он не создаст n
отдельных членов объекта. Он создает n
ссылки на единственный массив или объект и объединяет их в один массив. В базовой логике это имеет смысл. Как отметил @FelixKling в комментариях, он вполне соответствует тому, что вы ожидаете, т.е. заполнить этот массив этой одной вещью. Я бы все еще немного поспорил о его функциональности по двум причинам.
В каком случае кому-нибудь понадобятся ссылки n
, хранящиеся в массиве в том же месте в памяти? Вероятно, никогда . Как часто людям нужен Массив схожих объектов? Все время .
При передаче, например, Object Literal (.fill({a:1})
), я вижу логику заполнения массива ссылками, даже если он не совсем интуитивен. Если передать конструктор, я бы поспорил, что может иметь смысл больше иметь смысл для каждого члена в отдельности.
Таким образом, есть много нюансов и несоответствий с JavaScript, которые требуют знания для обхода - и, к сожалению, бесконечная ссылка , является одним из них - но, с другой стороны, единственный способ типично понять эти проблемы Существовать - значит безрассудно врезаться в них, так что будьте благодарны, что их не было в производстве!
Надеюсь, это поможет! Удачного кодирования!