Thursday, May 3, 2012

Self destructing Javascript function - How does it work?


So I found this piece of code and it obviously works (as it has been in production for years):




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
};



Curious to know, how does it work?



  1. How can it set itself to undefined within its body and try to delete itself?

  2. Does the browser know to not execute the undefined and delete until the call is finished? And how?

  3. If the browser deletes it right away, then what happens after? Does the last line run?

  4. Finally, do you guys see this leaking memory? If yes, how?


Source: Tips4all

3 comments:

  1. It's not setting itself to undefined, it's setting a reference to itself to undefined. If you think of a function as a block of code in memory, that block of code isn't deleted in this case, just the reference to it. You never explicitly delete anything in JavaScript, you simply remove references to it and leave it to the garbage collector to clean up. Note, this might not be the case for actual code, just heap objects, as its up to the engine how to treat it (interpret it, compile it, execute it on an abacus, whatever)
    Based on that logic, once the function is executing, the original reference to it is no longer required as it was needed only initially to transfer execution to it.
    You're misunderstanding JS evaluation as requiring a reference to it for every statement. In all likelihood, this method has been Just-In-Time compiled and is now executing just like any other non-JS function would run.
    There are no apparent memory leaks in the code above.


    Hopefully this is making sense.

    ReplyDelete
  2. window[someMethod] is simply a reference. Only the reference is deleted, not the function itself.
    Once the function is done, and all reference to it are removed, garbage collection should take care of it, avoiding memory leaks.

    ReplyDelete
  3. Remember you can't ever explicitly delete something in Javascript. All you can do is remove all the references to it and so let the garbage collector remove it on the next cycle. By the end of this function, the function itself is still in memory, but there are no external references to it. Next time the GC runs, it will spot this and deallocate its memory.

    ReplyDelete