2011-07-25 13 views
18

así que encontré este pedazo de código y es obvio que funciona (como lo ha sido en la producción por año):Función Javascript autodestructiva - ¿Cómo funciona?

window[someMethod] = function (tmp) { 
    callback({prop:"val"}, tmp); 

    // Garbage collect 
    window[someMethod] = undefined; 
    try { 
     delete window[someMethod]; 
    } 
    catch (e) { } 
    if (head) { 
     head.removeChild(script); 
    } 
    // head refers to DOM head elem and script refers to some script file elem 
}; 

curioso saber, ¿cómo funciona?

  1. ¿Cómo puede que se había fijado a undefined dentro de su cuerpo y try a delete sí?
  2. ¿El navegador saben a no ejecutar la undefineddelete y hasta que termine la llamada? ¿Y cómo?
  3. Si el navegador lo elimina de inmediato, ¿qué ocurre después? ¿Se ejecuta la última línea?
  4. Finalmente, ¿ustedes ven este filtrado de memoria? Si es así, ¿cómo?
  5. ventana

Respuesta

21
  1. No es el establecimiento en sí a indefinido, es establecer una referencia a sí mismo a no definido. Si piensa en una función como un bloque de código en la memoria, ese bloque de código no se elimina en este caso, solo la referencia al mismo. Nunca elimina explícitamente nada en JavaScript, simplemente elimina las referencias y deja que el recolector de basura lo limpie. Tenga en cuenta, esto podría no ser el caso para el código real, sólo los objetos del montón, ya que su hasta el motor de cómo tratarla (interpretarlo, compilarlo, ejecutarlo en un ábaco, lo que sea)
  2. Basado en esa lógica, una vez la función se está ejecutando, la referencia original ya no es necesaria ya que solo fue necesaria inicialmente para transferirle la ejecución.
  3. Está malinterpretando la evaluación de JS porque requiere una referencia para cada declaración. Con toda probabilidad, este método ha sido compilado justo a tiempo y ahora se está ejecutando como cualquier otra función que no sea JS.
  4. No hay pérdidas de memoria aparentes en el código anterior.

Esperemos que esto es dar sentido.

+1

Aunque la función de devolución de llamada conserva una referencia a 'tmp' en alguna parte, no veo por qué no habría una pérdida de memoria ... –

+1

Probablemente tienes razón, la respuesta actualizada. – yan

+0

Esto es muy útil. ¡Siento que tuve un brainstuff hoy antes de publicar esto! – Mrchief

2

[algunMetodo] es simplemente una referencia. Solo se borra la referencia, no la función en sí misma. Una vez que se realiza la función y se eliminan todas las referencias, la recolección de elementos no utilizados debe solucionarlo, evitando las pérdidas de memoria.

3

Recuerda que nunca puedes explícitamente borrar algo en Javascript. Todo lo que puede hacer es eliminar todas las referencias y dejar que el recolector de basura lo elimine en el próximo ciclo. Al final de esta función, la función en sí todavía está en la memoria, pero no hay referencias externas a ella. La próxima vez que se ejecute el GC, detectará esto y desasignará su memoria.

Cuestiones relacionadas