【问题标题】:Javascript object lifecycleJavascript 对象生命周期
【发布时间】:2015-07-23 12:22:07
【问题描述】:

我有一个如下所示的 Javascript 类:

var MYCLASS = function(elem, data, op) {

    var options = {};

    var loopForEver = function() {
        console.log('I cant stop me');
        setTimeout(function() {
            loopForEver();
        }, 1000);
    }
    this.init = function() {
        loopForEver();
    }
}

当我实例化类并调用 init 函数时,循环开始,我每 1 秒在控制台中获取文本:

var ins = new MYCLASS();
ins.init();

为什么当我将实例设置为空时,线程没有停止?或者每当我创建一个新实例并将其分配给以前的实例名称时,它都会增加调用次数。

在我的生产代码中,我没有无限循环,但我确实有一些业务逻辑。创建新实例时是否需要担心性能?

【问题讨论】:

    标签: javascript multithreading object


    【解决方案1】:

    当您调用 setTimeout 时,它不受调用它的函数的约束。您需要向名为timeOutID 的对象添加一个属性。只要该函数仍然需要被 setTimeout 之类的东西使用,它就会保持在范围内。

    var MYCLASS = function(elem, data, op) {
    
        var options = {};
        var timeOutID = null;
    
        var loopForEver = function() {
            console.log('I cant stop me');
            timeOutID = setTimeout(function() {
                loopForEver();
            }, 1000);
        }
        this.init = function() {
            loopForEver();
        }
        this.stop = function () {
          clearTimeout(timeOutID);
        }
    }
    

    【讨论】:

    • 但是为什么setTimeout回调能够执行loopForEver,显然已经不存在了?我想,这才是真正的问题。
    • 因为它确实存在。只要 setTimeout 之类的东西仍然需要使用该函数,它就会保持在范围内。 TL;DR 垃圾收集的语言。
    • 你可能也想把它放在答案中。
    【解决方案2】:

    你有一个memory leak

    换句话说,当现在无法访问的对象仍保留在内存中时,可能会发生内存泄漏,因为它们在call stack 中的其他位置被引用。

    使实例无效并不会从内存中清除对该对象的其他引用。 See this answer 到“Can an object automatically delete itself in javascript once it has achieved its purpose?

    实际上,您的setTimeout 调用是在重复创建一个新的execution context,每个都有自己不可触碰的Activation object,它们不受分配原始实例的影响到null

    摘自“Understanding delete(kangax 的 Perfect Kills) 是这样解释的:

    当一个函数被执行时,就说控制进入 执行上下文…;该代码可能会调用具有自己的执行上下文的函数;该函数可以调用另一个函数,因此 等等。

    即使函数递归调用自身,新的执行 每次调用都会输入上下文。

    …在函数代码中,变量对象是…所谓的激活 目的。每次执行上下文时都会创建激活对象 功能码已输入。

    请注意,Activation 对象是一种内部机制,永远不会 真正可以通过程序代码访问。

    如果你想使实例无效,你应该首先通过使用.clearTimeout()清除定时递归调用来清理它。

    【讨论】:

      猜你喜欢
      • 2011-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多