Замыкания в JavaScript
Счётчик на замыкании
var getId = function(){
var counter = 1;
return function(){
return counter++;
}
}
var res = getId();
console.log(res()); // 1
console.log(res()); // 2
Каждый раз вызывая getId(), будем получать увеличенное на 1 значение счётчика. Внутренняя переменная, отвечающая за счётчик, при этом недоступна извне: мы не сбросим его случайно или намеренно.
Буффер строк
Нужна функция, суммирующая входящие параметры в строке, с методом clear очистки содержимого. Реализация:
function makeBuffer() {
var res = "";
function buffer(newString){
if (newString) res += newString;
return res;
}
buffer.clear = function(){res = ""};
return buffer;
}
var buffer = makeBuffer();
var x = buffer(0);
x = buffer(1);
x = buffer(2);
console.log(x); // 12
buffer.clear();
x = buffer();
console.log(x); // пустая строка
x = buffer(3);
console.log(x); // 3
Задача про стрелков
Дан код. По логике, он должен выводить последовательно номера стрелков, однако всегда выводит 10:
function makeArmy() {
var shooters = [];
for (var i = 0; i < 10; i++) {
var shooter = function() { // функция-стрелок
alert( i ); // выводит свой номер
};
shooters.push(shooter);
}
return shooters;
}
var army = makeArmy();
army[0](); // стрелок выводит 10, а должен 0
army[5](); // стрелок выводит 10...
Причина ошибки ясна. Ниже два решения с замыканиями, без использования глобальных переменных или свойств объекта:
function makeArmy() {
var shooters = [];
for (var i = 0; i < 10; i++) {
var shooter = (function(x) {
return function(){ alert( x )}
})(i);
shooters.push(shooter);
}
return shooters;
}
var army = makeArmy();
army[0](); // 0
army[5](); // 5
function makeArmy() {
var shooters = [];
for (var i = 0; i < 10; i++) (function(x){
var shooter = function() {
alert( x );
};
shooters.push(shooter);
})(i)
return shooters;
}
var army = makeArmy();
army[0](); // 0
army[5](); // 5