这是Javascript中闭包的正确示例吗?

时间:2016-02-12 18:13:30

标签: javascript closures

我正在阅读一本关于Javascript的书,并尝试了一个关闭的例子。

function animateIt(id) {
   var elem= document.getElementById(id);
   var tick=0;

   var timer=setInterval(function() {
     if (tick<100) {

       elem.style.left = tick+"px";
       elem.style.top=tick+"px";
       tick++;
     } else {
       clearInterval(timer);
       assert(tick==100, "Tick Accessed and has value:- "+ tick);
       assert(elem, "element accessed");
       assert(timer, "timer accessed")
     }
   }, 10);
 }
 animateIt(box);      

但是计时器中的功能无法访问elem,tick等,而书中说它应该可以访问相同的内容。 请告诉我。

3 个答案:

答案 0 :(得分:0)

这可以视为闭包,函数animateIt包含变量idelem,因此如果您为不同的ID运行animateIt,它将正常工作。

答案 1 :(得分:0)

你没有给出整个代码(框,断言),但似乎有闭包。 假设现在执行animateIt函数,则会创建一个新的执行上下文,以及tick和elem等变量。

当执行到达此处时:

var timer=setInterval(function() {

创建一个新功能。这是一个匿名功能。它是setInterval中的函数,它引用了它的父函数(animateIt) 范围对象。范围对象包含vars - elem,tick。它有一个对范围对象的引用,因为函数anon位于函数animateIt内,词法上。父本身包含诸如

之类的变种
var elem= document.getElementById(id);
var tick=0;

这些变量由你的anon函数引用(在setInterval内),因为它们在animateIt的范围对象内,你的anon函数有一个对它的引用。

一旦animateIt函数执行上下文结束,你通过setInterval传递给事件队列的函数由于setInterval而继续执行自身开启和关闭,并且它可以访问曾经“存在”的函数的变量(在执行期间),但现在没有。该函数被称为animateIt,而闭包就是将这些变量(tick,elem)保存在内存中。

答案 2 :(得分:-1)

在未命名的函数调用中可见的tick变量(setInterval包含未命名的函数)是一个闭包。

每次函数调用都会创建Closure。

//source function which contain the variable: 
//lets consider it as a global function call
var tick=0;

(function() {
    //target function
    //1. closure is created on function call and 
    //2. another characterictic of closure is that 
    // source function must be parent of the target function
    console.log(tick); //so closure is equal to implicit parametrization
    //on target function call
}());

在前面的例子中,我调用一个函数隐式地将一个变量隐式添加到目标fucntion调用的内部“scope”。

我使用另一个名称来表示“闭包”(函数调用的隐式参数化)。

function animateIt(id) {

    var timer=setTimeout(function() {
        id="wow"; //important! there is no var keyword, so the outer variable is changed
    }, 1000);

   var timer=setInterval(function() { //on each function call a closure is created
     // in your case a built in function calls the function and 
     // on each call a closure is created
     console.log(id)
   }, 10);

 }

 animateIt("test");