Что я не понимаю в замыканиях?

Недавно Изучаю JS, но застрял на замыканиях. Прочитал уже кучу статей на эту тему, но все равно понять не могу почему func при вызове в if обращается к функции внутри inBetween(a,b)? И выходит, что переменная val является параметром function(x).Вопрос, наверное, задавался тысячу раз, но вразумительного ответа я не нашел.
function filter(arr, func) {
  var result = [];

  for (var i = 0; i < arr.length; i++) {
    var val = arr[i];
    if (func(val)) {
      result.push(val);
    }
  }

  return result;
}

function inBetween(a, b) {
    return function(x) {
      return x >= a && x <= b;
    };
  }

var arr = [1, 2, 3, 4, 5, 6, 7];
alert( filter(arr, inBetween(3, 6)) ); // 3,4,5,6
  • Вопрос задан
  • 468 просмотров
Решения вопроса 1
mbeloshitsky
@mbeloshitsky
Вебдев, систем оперейшонс, ж.д. автоматика
Ну, до меня уже все написали, но попробую по-другому, вдруг так понятно будет.

Суть замыканий в том, что вокруг функции замыкается ее контекст - окружение, в котором она была написана (именно написана, а не вызвана, поэтому еще иногда замыкания называют подробнее - замыкания лексического контекста). Это означает, что она всегда "видит" переменные, имеющиеся в этом контексте, даже если вызывается в совершенно других местах, где этими переменными и не пахнет.

В данном примере у вас

function(x)

замкнута в контексте функции

inBetween(a, b)

и поэтому будет всегда видеть переменные a и b.

--


И выходит, что переменная val является параметром function(x)

Это уже не про замыкания, это больше про функции высшего порядка.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 4
@nirvimel
Сама функция inBetween вызывается на этой строке.
alert( filter(arr, inBetween(3, 6)) ); // 3,4,5,6
Обратите внимание, она не передается в filter, а именно вызывается в этом месте. Дальше из себя она возвращает другую функцию function(x), внутри нее переменные a и b принимают конкретные значения 3 и 6 в этот момент. Дальше возвращенная функция function(x) передается в filter в качестве параметра func, именно она и вызывается в этой строке:
if (func(val)) {
Ответ написан
Комментировать
Olej
@Olej
инженер, программист, преподаватель
Что я не понимаю в замыканиях?

Ничего не понимаете ;-)

почему func при вызове в if обращается к функции внутри inBetween(a,b)?

Обращается не к "функции внутри", а inBetween() возвращает функцию.
Ответ написан
Комментировать
petermzg
@petermzg
Самый лучший программист
В Javascript функция является обьектом и этот обьект может сохранять связь на окружение, где был обьявлен.
Вызывая inBetween(3, 6) вы получаете в результате обьект/функцию function(x), которая запомнила окружение содержащее переменные (a, b). И полученную функцию вы передаете параметром func в filter(arr, func)

Выполняя if (func(val)) вы уже обращаетесь не к inBetween, а к той функции/обьекту внутри, которая помнит о своем окружнении.
Ответ написан
Комментировать
kamikadze1996
@kamikadze1996
{[]}
Вот аналогичный фильтр, но немного проще:

function filter(arr, a, b) {
var result = [];

for (var i = 0; i < arr.length; i++) {
if (arr[i] >= a && arr[i] <= b) {
result.push(arr[i])
}
}

return result;

}

var arr = [2, 5, 12, 66, 7, 4, 8, 3, 10]

filter(arr, 5, 10)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы