Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Замыкания в Javascript (https://javascript.ru/forum/misc/81782-zamykaniya-v-javascript.html)

denis_alekss 29.01.2021 00:00

Замыкания в Javascript
 
Вложений: 1
Очень много инфо о замыканих, но немного размыта информация самого смысла его использования.
Главный смысл замыканий сохранить локальную переменную после завершения функции и использовать при запуске 2-ого, 3-его, n-ого раза запуском главной функции в котором встроена внутренняя?

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
</head>
<body>
    <script>
var fn = (function() {
   var numberOfCalls = 0;
   return function() {
      return ++ numberOfCalls;
   }
})();
    </script>
</body>
</html>


Интересует, обычно функцию объявляют вначале круглые скобки, а затем фигурные и там список команд в фигурных, а здесь получается круглые и снова круглые? Разве так еще можно объявлять функцию?
Речь про концовку
Цитата:

})();
Переменной fn присвоилась функция, а затем какие-то скобки еще круглые пошли в самом конце функции, для чего?

Вот показал на скрине, функцию объявляют сразу с двумя подряд круглыми скобками что ли или это одновременно и объявление и вызов этой же функции? Разве так можно?

рони 29.01.2021 00:27

Цитата:

Сообщение от denis_alekss
это одновременно и объявление и вызов этой же функции?

да

Белый шум 29.01.2021 14:39

Цитата:

Сообщение от denis_alekss
Разве так еще можно объявлять функцию?

Это называется IIFE (Immediately Invoked Function Expression) и не имеет отношения к замыканиям.

Цитата:

Сообщение от denis_alekss
и использовать при запуске 2-ого, 3-его, n-ого раза запуском главной функции в котором встроена внутренняя?

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

denis_alekss 29.01.2021 21:30

Цитата:

Сообщение от Белый шум (Сообщение 533231)
Это называется IIFE (Immediately Invoked Function Expression) и не имеет отношения к замыканиям. х

А описанная внутренняя анонимная функция в функции fn разве не замыкание?

Когда я присваиваю переменной fn функцию, а в ней еще внутренняя анонимная функция, переменная fn содержит ссылку на функцию в функции, то есть 2 функции или ссылку только на анонимную внутреннюю одну?

рони 29.01.2021 21:34

Цитата:

Сообщение от denis_alekss
только на анонимную внутреннюю одну?

:yes:

denis_alekss 29.01.2021 21:41

Это все потому что стоит return function(),
А если бы return не стоял для вызова анонимной функции тогда все равно fn содержал бы ссылку на анонимную функцию или он содержит ссылку только на то что возвращает return главной функции fn?

рони 29.01.2021 21:46

denis_alekss,
console.log(fn)

рони 29.01.2021 21:52

denis_alekss,
если интересно уберите строку var numberOfCalls = 0; но сохраните прежний функционал и даже сделайте его более универсальным.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
</head>
<body>
    <script>
var fn = (function() {
   var numberOfCalls = 0;
   return function() {
      return ++ numberOfCalls;
   }
})();

console.log(fn());//1
console.log(fn());//2
console.log(fn());//3

var foo = (function() {
   /*var numberOfCalls = 0;*/
   return function() {
      return ++ numberOfCalls;
   }
})();

console.log(foo());//1
console.log(foo());//2
console.log(foo());//3

    </script>
</body>
</html>

denis_alekss 29.01.2021 22:00

Если запустить ваш вариант, вначале выдаст
1 2 3

А затем ошибку:

Цитата:

Uncaught ReferenceError: numberOfCalls is not defined
foo http://test.ru/:23

Если так:

var foo = (function() {
   /*var numberOfCalls = 0;*/
   return function() {
	   numberOfCalls = 0;
      return ++ numberOfCalls;
   }
})();


Выведет 3 раза подряд цифру 1 вместо 1 2 3

рони 29.01.2021 22:14

denis_alekss,
обе функции должны выдавать одно и тоже, плюс foo будет более универсальной.
это не меняйте
return function() {
      return ++ numberOfCalls;
   }

с остальным делайте, что хотите , var numberOfCalls = 0; не использовать


Часовой пояс GMT +3, время: 12:33.