Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: замыкания в JS
Форумы портала PHP.SU » Клиентская разработка » JavaScript & VBScript » замыкания в JS

Страниц (1): [1]
 

1. DlTA - 03 Июля, 2012 - 14:26:44 - перейти к сообщению
читаю http://habrahabr[dot]ru/post/38642/
Цитата:
Рассмотрим пример — функцию, возвращающую кол-во собственных вызовов:
CODE (javascript):
скопировать код в буфер обмена
  1. function createCounter() {
  2.    var numberOfCalls = 0;
  3.    return function() {
  4.       return ++numberOfCalls;
  5.    }
  6. }
  7. var fn = createCounter();
  8. fn(); //1
  9. fn(); //2
  10. fn(); //3

работает все верно но не могу понять почему именно так
немного перебиваем код:
CODE (javascript):
скопировать код в буфер обмена
  1. function vF() {
  2.    var pA = 0;
  3.    return function a() {
  4.       alert(++pA);
  5.    }
  6. }
  7.  
  8. var mvF = vF();
  9. mvF();
  10. mvF();
  11. mvF();

при выполнении данного кода в результате получаем 3 алерта 1,2, 3
но по моей логике функция vF вызывается 4 раза
первый раз: var mvF = vF();, ведь тут проиходит вызов, почему не происходит обработка???
2. Мелкий - 03 Июля, 2012 - 14:34:28 - перейти к сообщению
DlTA пишет:
ведь тут проиходит вызов

Не происходит.
Аналогично пхппешному, function() {} возвращает анонимную функцию, но не вызывает её.
3. LIME - 03 Июля, 2012 - 14:44:05 - перейти к сообщению
функция в жс это тоже тип данных
поэтому можно ее присвоить
что и происходит
возвращается тип-функция
и потом ее вызываем
(Добавление)
если короче при присвоении выполняется ф-ция возвращающая ф-цию
а не запускающая ее
(Добавление)
и имя ей давать нет смысла))
во 2м варианте
4. DeepVarvar - 03 Июля, 2012 - 15:22:42 - перейти к сообщению
Мелкий пишет:
но не вызывает её
DlTA верно подметил, специально чтобы вызвать а не присвоить ф-цию нужно указать скобки.
Мелкий не прав.
Он именно вызывает vF() которая возвращает тело ф-ции для внешней mvF
(Добавление)

IllusionMH - я кстати уже начал.

(Добавление)
Область видимости.
Вот в текущей области:
CODE (javascript):
скопировать код в буфер обмена
  1. function a() {
  2.   alert("xxx");
  3. }
  4. var x = a;
  5. x();
  6. x();

А вот в обертке:
CODE (javascript):
скопировать код в буфер обмена
  1. function wrapper() {
  2.   return function a() {
  3.     alert("xxx");
  4.   }
  5. }
  6. var x = wrapper(); // вот она возвращает тело для ф-ции "a"
  7. x();
  8. x();
5. DlTA - 03 Июля, 2012 - 15:53:04 - перейти к сообщению
JS таки удивительный язык
перепробовал
варианты: (Отобразить)

до меня наконец дошло что конструкции типа pA = function(){ return ++a;}
определяют метод, хотя это было понятно и раньше
но тогда не понятно, если взять мой первый пример
метод mvF() где относительно него хранятся свойство var pA;?
6. IllusionMH - 03 Июля, 2012 - 15:56:46 - перейти к сообщению
Мне сейчас кажется, что все три ответа говорят об одном - происходит 4 вызова функций:
1 раз - vF() (легко проверить вызвав alert внутри нее)
3 раза функция-результат ее работы (a) Улыбка
Просто немного не понял друг друга.

Если есть желание сразу вызвать, то
CODE (javascript):
скопировать код в буфер обмена
  1. var mvF;
  2. (mvF = vF())();



более интересен результат
CODE (javascript):
скопировать код в буфер обмена
  1. var mvF1, mvF2;
  2. mvF1 = vF();
  3. mvF2 = vF();
  4. mvF1(); //1
  5. mvF1(); //2
  6.  
  7. mvF2(); //1
  8.  
  9. mvF1(); //3
  10.  
  11. mvF2(); //2

т.е. каждый вызов функции создает свою отдельную область видимости с локальной переменной pA.


DeepVarvar, понял тебя
7. DeepVarvar - 03 Июля, 2012 - 15:58:29 - перейти к сообщению
DlTA пишет:
где относительно него хранятся свойство var pA;

оно хранится внутри vF, но у внешней mvF есть ссылка на внутреннюю a, которая ищет pA "вне себя" ранее, выше по области видимости, т.к. если у себя она не найдет что-то, то пойдет искать выше, пример:
CODE (javascript):
скопировать код в буфер обмена
  1. var x = 22;
  2. function a() {
  3.  alert(x);
  4. }
  5. a();
8. Мелкий - 03 Июля, 2012 - 16:00:05 - перейти к сообщению
DeepVarvar пишет:
Мелкий не прав.

Почему? А, я в vF / mvF запутался. Вопрос неверно прочитал.

vF вызывается всего 1 раз, здесь: var mvF = vF();
Затем 3 раза вызывается алерт из каллбека, который вернула функция vF. Но сама vF не вызывается.
9. DeepVarvar - 03 Июля, 2012 - 16:02:49 - перейти к сообщению
Мелкий пишет:
Но сама vF не вызывается
Она по сути уже даже не нужна, т.к. выполняет роль обертки, сплюнула ссылку на а и все.
10. IllusionMH - 03 Июля, 2012 - 16:07:15 - перейти к сообщению
DlTA пишет:
, метод mvF() где относительно него хранятся свойство var pA;?

Порядок поиска переменной в функции такой:
1) У себя среди локальных переменный
2) В своем prototype
3) [Поднимаемся на уровень верх, т.е теперь пункты 1-2 повторяются для родителя vF]
ищем среди локальных переменных функции vF (находим pA и используем ее)

(в конкретном примере это уже не происходит, но в теории)
4) если не нашли - ищем в прототипе vF
5) Снова поднимаемся вверх и т.д.
11. DeepVarvar - 03 Июля, 2012 - 16:16:51 - перейти к сообщению
Упс ай, а дид ит эгейн: http://habrahabr[dot]ru/post/146784/
Хотя и говорят что не актуально уже, все-же будьте аккуратнее с этим.
12. IllusionMH - 03 Июля, 2012 - 16:23:25 - перейти к сообщению

DeepVarvar, за ссылочку спасибо

 

Powered by ExBB FM 1.0 RC1