Autor Zpráva
weroro
Profil
Ahoj,

riešim otázku toho, či je možné nejak optimálne upraviť prípad, kedy mám NodeList nad ktorým potrebujem volať array funkcie (napr. Array.filter) bez toho aby som musel vytvárať duplicitu v pamäti.

Čo považujem za duplicitu:

const nodeList = document.querySelectorAll('div');

let elementArray = [...nodeList]; // duplicita
//let elementArray = Array.from(nodeList); // duplicita

elementArray = elementArray.filter(element => !element.closest('.exclude'));


Existuje nejaký postup/spôsob ako sa vyhnúť takejto duplicite v pamäti?
Ako to chápem a prečo to nazývam duplicitou (možno sa mýlim, tak budem rád ak ma opravíte):

nodeList je v pamäti uložený podobne ako array, čiže si alokuje celý blok pamäte. Následne ale vytváram novú alokáciu bloku pamäte s prakticky rovnakým obsahom, čiže to považujem za duplicitu. Možno by šlo, premazať pamäť ale to nie je riešenie, ja sa chcem obecne vyhnúť tej duplicite, kvôli tomu aby sa zbytočne nepúšťal garbage collector.

Ďakujem za váš čas.

// edit
Napadlo ma, že či by reassign do pôvodnej premennej nebolo riešením.
let nodeList = document.querySelectorAll('div');
nodeList = [...nodeList];

Otázne je, ako sa zachová interpreter, v takomto prípade. Či reálne iba prepíše dáta na adrese, alebo či pred tým zmaže predošlé dáta, pretože to nie je podľa mňa ako keď reassign-ujem premennú, v ktorej mám obyčajný string.
Radek9
Profil
weroro:
Jednoduchá odpověď? Neřeš to. Je to jen NodeList pointerů a následně pole pointerů. Ty samotné elementy se neduplikují. Z hlediska paměti je to naprosto minimální overhead a gc by se časem volal tak jako tak.

Pokud tě štve, že na to máš separátní proměnnou, tak to přece můžeš udělat takhle:
let elementArray = [...document.querySelectorAll('div')].filter(element => !element.closest('.exclude'))
weroro
Profil
Áno, ja to mám v kóde tak ako je v tvojej odpovedi.
let containerElements = [...dom.querySelectorAll('div')];

if (excludedParentSelector?.trim?.()) {
    containerElements = containerElements.filter(element => !element.closest(excludedParentSelector));
}

Iba ma zaujímalo, či sa dá nejak vyhnúť tej konverzii. Ak ale chápem správne, tak priame "rozbitie" toho NodeList-u do poľa, by mohlo zamedziť tomu aby sa to najprv uložilo. deštruuje sa to za behu. Takže nad tým nemusím v takom prípade premýšľať.

Ďakujem
Radek9
Profil
weroro:
Ak ale chápem správne, tak priame "rozbitie" toho NodeList-u do poľa, by mohlo zamedziť tomu aby sa to najprv uložilo. deštruuje sa to za behu.
To je implementační detail, který tě vlastně nemusí úplně zajímat. Je možné, že to gc smaže hned, nebo až v nějaký vhodnější moment (typicky když velikost alokované paměti překročí nějakou stanovenou hranici a zrovna se nic moc jiného neděje). Moderní enginy to už mají docela vychytané, nestresuj se tím. ;-)

Vaše odpověď

Mohlo by se hodit

Neumíte-li správně určit příčinu chyby, vkládejte odkazy na živé ukázky.
Užíváte-li nějakou cizí knihovnu, ukažte odpovídajícím, kde jste ji vzali.

Užitečné odkazy:

Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0