@Kolya112151

Замыкания не существует?

Изучаю эти "замыкания". Говорят, замыкание, это когда функция имеет доступ к переменной из функции, которая уже завершила свою работу. И приводят этот пример:

function one() {
  const oneVar = 'Hello!'

  function two() {
    console.log(oneVar)
  }

  return two
}

const three = one()

three()


Якобы в этом примере three() имеет доступ к переменной oneVar, благодаря замыканию. Что за бред? three() просто вызывает функцию one(), причём тут какое-то замыкание? Просто вызов той же самой функции, причём доступ к переменной как раз происходит во время работы функции. То есть функция не завершила свою работу.
  • Вопрос задан
  • 247 просмотров
Пригласить эксперта
Ответы на вопрос 4
Stalker_RED
@Stalker_RED
Я немного добавил наглядности
function one() {
  const oneVar = 'Hello!'
  let counter = 0;
  console.log('функция one работает прямо сейчас, в счетчике', counter)

  function two() {
    console.log(oneVar, ++counter)
  }
  
  console.log('функция one почти завершилась, в счетчике все еще ', counter);
  return two
}

const three = one();
console.log('функция one точно завершилась, даже return сработал');
console.log('в переменной three сейчас функция two()');
console.log(three);


three();
three();
three();
console.log('обожемой, мы видим как менялась переменная в уже завершенной функции. чераная магия? нет - это называется замыкание!');

выхлоп:
"функция one работает прямо сейчас, в счетчике", 0
"функция one почти завершилась, в счетчике все еще ", 0
"функция one точно завершилась, даже return сработал"
"в переменной three сейчас функция two()"
function two() {
  console.log(oneVar, ++counter)
}
"Hello!", 1
"Hello!", 2
"Hello!", 3
"обожемой, мы видим как менялась переменная в уже завершенной функции. чераная магия? нет - это называется замыкание!"
Ответ написан
Комментировать
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Функция one() определяет переменную oneVar. Затем в ней определяется функция two(), в лексическое окружение которой попадает oneVar. В конце своей работы функция one() возвращает в качестве результата функцию two().
В переменную three записывается результат работы one(), то есть функция two(). Несмотря на то, что one() уже закончила работу, переменная oneVar сохраняется в лексическом окружении функции two().
При вызове three() фактически вызывается two(), в которой переменная oneVar доступна для использования.
Ответ написан
Замыкания есть.
Только в спецификации это называется "Lexical Environment" (п 8.1)
https://262.ecma-international.org/10.0/#sec-lexic...
Вот ещё с MDN:
https://developer.mozilla.org/en-US/docs/Web/JavaS...
Ответ написан
Комментировать
HemulGM
@HemulGM
Delphi Developer, сис. админ
Что за бред? three() просто вызывает функцию one(), причём тут какое-то замыкание?

three() - это ссылка на two(), а не на one() и соответственно вызывает код two(), которая ссылается на переменную функции one();

Вот тебе пример (но на Делфи). Отличий по сути нет. Вызов функции, которая помещена в getOne изменяет значение параметра, который был передан в canGetCount()
function canGetCount(N: Integer): TFunc<string>;
begin
  Result :=
    function: string
    begin
      Dec(N);
      Exit(IfThen(N >= 0, 'yes', 'no'));
    end;
end;

begin
  var getOne := canGetCount(2);
  writeln(getOne()); //yes
  writeln(getOne()); //yes
  writeln(getOne()); //no
  readln;
end.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Похожие вопросы