2016-02-12 4 views
-1

Я просматриваю книгу на Javascript и пробовал один из примеров ее закрытия.Является ли это правильным примером закрытия в 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);  

но функция таймера не имеет доступа к элем, тик и т.д., тогда как книга говорит, что должны иметь доступ к тем же самым. Пожалуйста, дайте мне знать.

+0

Где находится "box"? – guest271314

+1

_ «не имеет доступа к элементу, тике и т. Д.» _ Как вы знаете, что у вас нет доступа к ним? Вы получаете ошибки на консоли, говоря, что их не существует? Единственная проблема, которую я вижу в коде, заключается в том, что она может выполняться до того, как элемент, идентифицированный 'id', существует так, что' elem' в конечном итоге будет «null» –

+1

[It works] (https://jsfiddle.net/r2u5r8f9/) – Oriol

ответ

-1

Указанная галочка, которая видна внутри вызова неназванной функции (setInterval содержит неназванную функцию), является закрытием.

Закрытие создается для вызова функции.

//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.

Я использую другое имя для «закрытия» (неявная параметризация при вызове функции).

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"); 
+1

Нет, замыкание создается при вычислении определения функции; фиксируя лексический охват в точке его определения. То, что у вас есть, есть область действия. –

+0

Новая область создается для каждой оценки тела функции, в которой привязаны аргументы и локальные переменные, в результате вызова функции. –

+0

Я думал, что «scope» расшифровывает лучшее хранилище varibale на таких языках, как C#, потому что следующее выражение {} определенно очищает внутренние переменные (нефункциональный язык). Поэтому я считаю, что мы не должны использовать термин «scope» в javascript, потому что закрытие создается при вызове функции (это поведение функционального языка). В качестве примера http://stackoverflow.com/a/111111/1145224 Пример 7. Как вы думаете, Дэн? – Spirit

0

Это можно рассматривать как закрытие, функция animateIt содержит переменные id и elem, так что если вы будете запускать animateIt для различных идентификаторов будет работать правильно.

0

Вы не указали весь код (поле, утверждать), но, как кажется, есть замыкание. Предполагая, что функция animateIt теперь выполнена, создается новый контекст выполнения, наряду с vars, такими как 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, а закрытие - это то, что сохранили эти vars (tick, elem) в памяти.

Смежные вопросы