我制作了一个图像滑块" 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);
答案 0 :(得分:2)
我尝试删除var foo =并继续工作,这对我来说很惊讶。是什么让它继续工作?
因为定时器系统保留了对它的引用,因为它设置了对通过setInterval
和setTimeout
引用它的函数(闭包)的回调。因此,只要这些计时器仍然存在,就会保留对其必要部分的引用。
这里给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
大约一半的效果。