自我毁灭Javascript功能 - 它是如何工作的?

时间:2011-07-25 14:28:24

标签: javascript closures

所以我找到了这段代码,它显然有效(因为它已经在生产多年):

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

很想知道,它是如何运作的?

  1. 如何将自己设置为undefined及其try内的delete undefined本身?
  2. 在呼叫结束之前,浏览器是否知道不执行delete和{{1}}?怎么样?
  3. 如果浏览器立即将其删除,那么之后会发生什么?最后一行是否运行?
  4. 最后,你们看到这个泄漏的记忆吗?如果是,怎么样?

3 个答案:

答案 0 :(得分:21)

  1. 它没有将本身设置为undefined,它将自己的引用设置为undefined。如果您将函数视为内存中的代码块,则在这种情况下不会删除该代码块,只是对它的引用。您从未在JavaScript中明确删除任何内容,只需删除对它的引用并将其留给垃圾收集器进行清理。注意,这可能不是实际代码的情况,只是堆对象,因为它取决于引擎如何对待它(解释它,编译它,在算盘上执行它,等等)
  2. 基于该逻辑,一旦该函数执行,就不再需要对它的原始引用,因为最初只需要将执行转移到它。
  3. 您误解了JS评估需要为每个语句引用它。很有可能,这个方法已经被Just-In-Time编译,现在正在执行,就像任何其他非JS函数一样。
  4. 上面的代码中没有明显的内存泄漏。
  5. 希望这是有道理的。

答案 1 :(得分:3)

请记住,您无法显式删除Javascript中的内容。您所能做的就是删除对它的所有引用,然后让垃圾收集器在下一个周期中将其删除。在此函数结束时,函数本身仍在内存中,但没有外部引用。下次GC运行时,它会发现它并释放其内存。

答案 2 :(得分:2)

window [someMethod]只是一个引用。仅删除引用,而不删除函数本身。 一旦函数完成,并且删除了对它的所有引用,垃圾收集应该处理它,避免内存泄漏。