• Почему происходит магия в JS коде?

    Я не знаток CoffeeScript, но судя по всему, ваш скрипт генерирует вот такой JS код (ссылка на jsfiddle):
    var a = [ { id: 0 }, { id: 1 }, { id: 2 } ];
    for(var i = 0; i != a.length; ++i)
    {
        var el = a[i];
        setTimeout(function() { 
            console.log('timeout',el);
        },100);
    }


    В этом случае вы замыкаете вашу анонимную функцию на переменную el, значение которой меняется на каждой итерации. Таким образом после окончания цикла значение el будет равно последнему элементу массива. А так как анонимная функция будет вызвана после завершения цикла, то это приведет к результату, который вы описали:
    timeout Object { id: 2 }
    timeout Object { id: 2 }
    timeout Object { id: 2 }


    Для того, чтобы ваш код выполнялся правильно - можно сделать такой трюк: передавать el в качестве аргумента в некую функцию, которая возвратит нам коллбэк функцию (пример на jsfiddle):
    var a = [ { id: 0 }, { id: 1 }, { id: 2 } ];
    var createCB = function(e){
        return function() { 
            console.log('timeout',e);
        };
    };
    for(var i = 0; i != a.length; ++i)
    {
        var el = a[i];
        setTimeout(createCB(el),100);        
    }


    В этом случае при создании коллбэка у нас в области видимости будет всегда текущее значение el:
    timeout Object { id: 0 }
    timeout Object { id: 1 }
    timeout Object { id: 2 }
    Ответ написан
    1 комментарий