Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   счетчик в функции - как это работает ? (https://javascript.ru/forum/misc/37294-schetchik-v-funkcii-kak-ehto-rabotaet.html)

macdack 14.04.2013 16:57

счетчик в функции - как это работает ?
 
вот есть пример в учебнике:

function makeCounter() {
var currentCount = 0;      /объявляется переменная внутри функции со значением 0
return function()             /а это чо за
{currentCount++;return currentCount;};     /а это чо за
}
var counter = makeCounter();

// каждый вызов увеличивает счётчик
counter();
counter();

alert( counter() ); // 3


не могу понять как это работает
зачем внутри функции еще одна функция ?
проще или иначе никак нельзя сделать ?
и почему при каждом вызове counter() меняется currentCount если всегда есть строка var currentCount = 0

megaupload 14.04.2013 17:04

Цитата:

Сообщение от macdack
и почему при каждом вызове counter() меняется currentCount если всегда есть строка var currentCount = 0

эта строка выполняется ТОЛЬКО ОДИН РАЗ, когда вызывается функция в которой находится эта строка,

смотрим как же называется эта функция? а называется она makeCounter

смотрим СКОЛЬКО РАЗ вызывается makeCounter?? праавильно, вызывается она ОДИН РАЗ на 5 строчке

чо нам эта функция возвращает? правильно, другую функцию..

куда мы кладем то что нам возвратила функция makeCounter?? прааавильно, в переменную counter

то есть теперь у нас в переменной counter лежит та другая функция которую возвратила makeCounter когда мы её вызвали.. все 5 строчка.

даальше, что делает эта возвращенная функция которая лежит теперь в переменной counter ?

праавильно, смотрим что же она делает

function() { currentCount++;   return currentCount }


она делает 2 действия, увеличивает счетчик на один currentCount++;

и возвращает значение этого щетчика return currentCount



ВОПРОС, где хранится щетчик? везд создали то мы его в контексте функции makeCounter еще когда его там через var создавали, но функция свое отработала и завершилась, где теперь хранятся её переменные?

А вот тут то и включается движок яваскрипта, чем завершить любую функцию и удалить из памяти все её переменные, он смотрит А ЕСТЬ ЛИ ЧТО ТО ЧТО ИХ ИСПОЛЬЗУЕТ или ВОЗМОЖНО БУДЕТ ИСПОЛЬЗОВАТЬ ПОТОМ)?\

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

а пихает он её в ЗАМЫКАНИЕ этой функции))) это если в кратце говорить..

macdack 14.04.2013 17:15

да почему ОДИН РАЗ то !?
не врубаюсь категорически ))

я рассуждаю так:

makeCounter - это переменная которая ссылается на нашу функцию
переменная counter ссылается также на эту функцию
при вызове counter() - вызывается функция makeCounter а у нее всегда var currentCount = 0
сколько раз написано counter() - столько раз и запускается подпрограмма на которую ссылается переменная counter

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

megaupload 14.04.2013 17:24

Цитата:

Сообщение от macdack
при вызове counter() - вызывается функция makeCounte

при вызове counter() - вызывается ТО ЧТО ВЕРНУЛА функция makeCounte, которая вызывалась один раз. кэп

function ololo (){
   return 11
}

var counter = ololo()


чо у нас в переменной counter лежит? функция ololo или то что она ВЕРНУЛА???

она ж блять ВЫЗЫВАЕТСЯ, ВЫПОЛНЯЕТСя и чо то блять ВОЗВРАЩЯЕТ) видешь скобочки после неё стоят)? значит она выполняется и после выполнения на свое место как бы подставляет результат выполнения

(то что она подставит на свое место, после вызова, указывается оператором return внутри самой функции)

macdack 14.04.2013 17:34

а
балин я тупой

я не заметил - var counter = makeCounter()


тоесть - есть программа внутри программы которая выдает эту программу как результат своей работы
а работа однократная, а переменная в ней сохраняется пока есть ссылки на нее и меняется когда ее меняет внутренняя программа

а часто это в реальной жизни бывает полезно ?
можете ли вы привести какойнибуть распространенный пример пжста
или же это чисто теоретический переподворот с подвыпердвертом дабы пролюстрировать замыкательства ?

megaupload 14.04.2013 18:04

Цитата:

Сообщение от macdack
тоесть - есть программа внутри программы которая выдает эту программу как результат своей работы
а работа однократная, а переменная в ней сохраняется пока есть ссылки на нее и меняется когда ее меняет внутренняя программа

да

megaupload 14.04.2013 18:09

Цитата:

Сообщение от macdack
а часто это в реальной жизни бывает полезно ?
можете ли вы привести какойнибуть распространенный пример пжста

ну например если я хочу добавить в приложение какой-то модуль, а со мной работает еще 100000 00000 0000 00 программистов которые тоже пихают свои мордули, то мы не хотим засирать глобальное пространство своими переменными)

и мы сохраняем из в замыкании, а внаружу отдаем только обьект для работы с нашим модулем)



типа module = (function(){ /*тут код модуля*/ })() //создадим функцию, возьмем её в скобочки и сразу вызовем


вот например

module = (function(){

  var bla, bfdffla, blafd = 11;
  function ololo (){ } // обьявляем тут разные функции все дела
                               //делаем чо хотим

  //а внаружу отдаем только обьект для управления нашим модулем извне
  return {
       on : function(){},
       off : function(){},
  }

})();


и вот эти вот функции on и off могут иметь доступ к тому что внутри модуля)) пнятно)?

zebra 14.04.2013 18:09

Почитайте про замыкания

macdack 14.04.2013 18:43

megaupload, наверное есть и другие архитектурные способы достижения задачи порядка в пространстве имен без привлечения анонимной функции ?

и может быть вы подскажете альтернативный пример спасибо
(мне не нравится сама идея анонимной функции - както нарушение логичности и стройности и простоты)

megaupload 14.04.2013 20:09

добавим логирование на алерт, настоящий алерт хранится в замыкании этой функции так как ссылку на него мы передали как аргумент



alert = (function (alert) {

	return function () {
		console.log.apply(console, arguments);
		return alert.apply(window, arguments);
	}

})(alert);


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