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 22:25

Вложений: 1
Ничего не менял, запустил ваш код, функция foo не определена выдает, вот фото ниже, сделал скриншот

рони 29.01.2021 22:40

Цитата:

Сообщение от denis_alekss
запустил ваш код,

а зачем? вы что-то добавили, изменили? зачем запускать то, что является условием задачи, а не её решением?

denis_alekss 29.01.2021 22:58

Если для теста написать даже вот так:
var foo = (function() {
   /*var numberOfCalls = 0;*/
  
  alert('Привет');
 return  function () {
	   return alert('Пока');
   }
})();


Вначале простреляет 1 Привет, а затем 3 пока, и каждый раз когда будет выводится слово Пока, будет выводится в консоль undefined, значит переменная foo ссылается только на внутренню анонимную функцию ?

НА эту если возвратимся к коду в 1-ом посте:

return function() {
      return ++ numberOfCalls;
   }

рони 29.01.2021 22:59

denis_alekss,
надо дописать в пару мест недостающее, что-бы код стал рабочим.
var foo = (function() {
   return function() {
      return ++ numberOfCalls;
   }
})();

рони 29.01.2021 23:09

denis_alekss,
ок ... что-то пошло не так, наверно я плохо сформулировал задачу...

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

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

denis_alekss 29.01.2021 23:14

Этим кодом вы показываете что ссылка все-таки идет на внутреннюю функцию, вы просто передаете аргумент 0 функции fn, а им пользуется внутренняя анонимная функция. Если передать вместо 0 передать к примеру 8, счетчик пойдет с 9 из-за инкремента и вся работа пойдет во внутренней а не со внешней функции

рони 29.01.2021 23:27

denis_alekss,
:yes:

denis_alekss 29.01.2021 23:45

Немного другая версия этого же случая:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
</head>
<body>
    <script>
Function.prototype.bind = function(context) {
   var fn = this;
   return function() {
      return fn.apply(context, arguments);
   };
}
var HelloPage = {
   name: 'Вася!!!',
   init: function() {
      alert('Hello, ' + this.name);
   }
}
window.onload = HelloPage.init.bind(HelloPage); 
</body>
</html>


Если поменять эту строку:
Function.prototype.bind

на
Function.prototype.call

разницы при выводе не происходит.

Если поменять эту строку:
window.onload = HelloPage.init.bind(HelloPage);

на
window.onload = HelloPage.init.apply(HelloPage);

Также вывод одинаковый.

В этом месте также используется замыкание
Function.prototype.call = function(context) {
   return function() {
      return this.apply(context, arguments);
   };
}

Здесь this ссылается на объект HelloPage благодаря функции call или bind если указать в строке Function.prototype.bind? Можно ли обойтись в этом коде для получения идентичного результата без замыканий если я хочу вызвать метод объекта передав свойство Петя с этого же объекта в метод?

Белый шум 30.01.2021 04:11

Цитата:

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

Замыкание, но оно не имеет отношения к IIFE.

Можно определить замыкание и без IIFE, просто внешнюю функцию надо будет вызвать явно:
<body>
<script>
function getMyClosure(){
   var count = 0;
   var closure = function(){ return count++; }
   return closure;
}

var counter = getMyClosure(); //вызываем явно и сохраняем ссылку на внутреннюю функцию в нашей переменной
</script>
<button onclick="alert(counter())">Press Me</button>
</body>

denis_alekss 31.01.2021 18:58

Цитата:

var counter = getMyClosure(); //вызываем явно и сохраняем ссылку на внутреннюю функцию в нашей переменной
Зачем нужно создавать ссылку counter на функцию getMyClosure?
Почему нельзя просто вызвать getMyClosure() и передать в Onclick?


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