Mientras experimentaba con mantener las funciones en espacios de nombres separados e intentaba liberar la memoria consumida por los espacios de nombres que ya no se necesitaban, codifiqué esto por accidente sin siquiera pensar en el hecho de que está eliminando el espacio de nombres N desde uno de sus propios métodos, N.loader() . Al principio, tenía el unload('N') en finally , y después de darme cuenta de que se ejecutaría solo después de inyectar el nuevo script, moví el unload() antes de la inyección.
Incluso si el script inyectado elimina window.N , se está ejecutando desde el último .then() del método N.loader() antes de que se ejecute finally .
Por lo tanto, estoy confundido acerca de si esto realmente está eliminando el espacio de nombres y sus métodos de la memoria, o si solo los hace inaccesibles desde el código JS restante.
¿Podría explicar cómo funciona esto detrás de escena? ¿Cómo podría eliminarse el objeto principal del método antes de que el método haya terminado de ejecutarse?
Gracias.
"use strict"; try { window.N = new Object(); window.N.loader = function() { fetch(url, {}) .then( response => {}) .then( data => { return fetch(url,{}); }) .then( response => { }) .then( data => { unload('N'); let d = new DOMParser(), b = d.parseFromString( data, 'text/html' ); // inject new script. // console.log( window.N ) => undefined. }) .catch( error => { console.error('Error:', error); }) .finally( () => { // too late to delete window.N. // New script already injected. }); }; // Close window.N.loader function unload(f) { console.log( delete window[f] ); // => true } window.N.loader(); } catch (err) { console.log(err); } finally { }Sí, puede, con una salvedad. En realidad, no estás eliminando el objeto. Más bien, solo está eliminando el enlace entre la propiedad de la ventana y el objeto en la memoria.
Cuando delete , el objeto en esa propiedad seguirá existiendo. Si nada más tiene una referencia a él, se recolectará la basura en unos segundos, por lo general. Si algo más todavía tiene una referencia a él, nunca se recolectará basura a menos que algo más cambie.
Para un ejemplo más simple:
(() => { const theNamespace = { fn() { delete window.propertyA; } }; window.propertyA = theNamespace; window.propertyB = theNamespace; })(); window.propertyA.fn(); console.log(window.propertyB);o solo haciéndolos inalcanzables desde el código JS restante
Correcto, siempre que algo tenga una referencia al mismo objeto, el objeto permanecerá (en su mayor parte, vea marcar y barrer ). Si elimina window.N , otras referencias a window.n dejarán de funcionar, pero si algo más tiene una referencia al mismo objeto en alguna otra propiedad o identificador, esas referencias seguirán funcionando.