“类”继续工作而不是全局引用

时间:2014-07-18 20:37:14

标签: javascript garbage-collection

我制作了一个图像滑块" class"并最初将其实例化为:

var foo = new Slider(document.getElementById("featuredSlider"), 900);

我尝试删除var foo =并继续工作,这对我来说很惊讶。是什么让它继续工作?不在全球范围内引用它是不是一个坏主意?

在旁注中,"featuredSlider"id代码的<div>。它包含一些<a&gt;标签,每个标签都包含<img>个标签。

function Slider(inElement, inStep) {
    if (!inElement) return;

    this.element = inElement;
    this.start = 0;
    this.end = 0;

    var self = this;
    var limit = inElement.getElementsByTagName("a").length*inStep;
    setInterval(function() {
        self.start = self.end;
        self.end = (self.end+inStep)%limit;
        self.animate(this.start < this.end ? 1 : -1);
    }, 3000);
}

Slider.prototype.animate = function(inZeno) {
    this.start += ((this.end-this.start)>>2)+inZeno;
    this.element.style.left = this.start+"px";

    if (this.start !== this.end) {
        var self = this;
        setTimeout(function() {
            self.animate(self.start < self.end ? 1 : -1);
        }, 33);
    }
}

//new Slider(document.getElementById("featuredSlider"), 900);
var foo = new Slider(document.getElementById("featuredSlider"), 900);

1 个答案:

答案 0 :(得分:2)

  

我尝试删除var foo =并继续工作,这对我来说很惊讶。是什么让它继续工作?

因为定时器系统保留了对它的引用,因为它设置了对通过setIntervalsetTimeout引用它的函数(闭包)的回调。因此,只要这些计时器仍然存在,就会保留对其必要部分的引用。

这里给setInterval的功能:

setInterval(function() {
    self.start = self.end;
    self.end = (self.end+inStep)%limit;
    self.animate(this.start < this.end ? 1 : -1);
}, 3000);

是对Slider的调用的结束。因此,只要闭包(函数)在周围,闭包内范围内的所有东西都会被保留。由于永远不会取消该计时器,因此计时器系统会保留这些参考值。 (如果“封闭”不熟悉或只是略微熟悉,请不要担心:Closures are not complicated。)

  

不全球引用它是不是一个坏主意?

不,那没关系。如果它继续工作并且您不需要引用,则无需存储对它的引用。当许多人使用script.aculo.us时,这是一个非常常见的模式,它使用了new大约一半的效果。