Меню

Замыкания в Java Script (Closures)

08.05.2018 - java script, ЯП
Замыкания в Java Script (Closures)

Замыкания

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

Классический пример замыкания

function foo() {
    var a = 2;
    function bar() {
        console.log( a );
    }
    return bar;
}
var baz = foo();
baz(); // 2 -- Ого, замыкание только что было раскрыто, мужики!

Классический примерз замыкания в цикле:
Так работать не будет!
Даже если мы поставим таймеру отсрочку 0 мс. Так как содержимое таймаута выполнится только после завершения цикла.

for (var i=1; i<=5; i++) {
    setTimeout( function timer(){
        console.log( i );
    }, i*1000 );
}

А так будет

for (var i=1; i<=5; i++) {
    (function(j){
        setTimeout( function timer(){
            console.log( j );
        }, j*1000 );
    })( i );
}

А так еще проще

for (let i=1; i<=5; i++) {
    setTimeout( function timer(){
        console.log( i );
    }, i*1000 );
}

Модуль

Одно из самых полезных использований замыкания — модуль
Выглядит это следующим образом:

function CoolModule() {
    var something = "cool";
    var another = [1, 2, 3];
    function doSomething() {
        console.log( something );
    }
    function doAnother() {
        console.log( another.join( " ! " ) );
    }
    return {
        doSomething: doSomething,
        doAnother: doAnother
    };
}
var foo = CoolModule();

foo.doSomething(); // cool
foo.doAnother(); // 1 ! 2 ! 3

Есть 2 требования, которые должны выполняться для шаблона модуля:
* Должны быть внешняя окружающая функция и она должна быть вызвана хотя бы раз (каждый раз создается новый экземпляр модуля)
* Окружающая функция должна возвращать хотя бы одну внутреннюю функцию, для того, чтобы у этой внутренней функции было замыкание на приватную область видимости и был доступ и/или возможность изменения ее внутреннего состояния.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *