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

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: замыкания в JS

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


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

> Описание: непонятки в выполнении
DlTA
Отправлено: 03 Июля, 2012 - 14:26:44
Post Id



Постоянный участник


Покинул форум
Сообщений всего: 2952
Дата рег-ции: Окт. 2010  


Помог: 53 раз(а)




читаю 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();, ведь тут проиходит вызов, почему не происходит обработка???
 
 Top
Мелкий Супермодератор
Отправлено: 03 Июля, 2012 - 14:34:28
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




DlTA пишет:
ведь тут проиходит вызов

Не происходит.
Аналогично пхппешному, function() {} возвращает анонимную функцию, но не вызывает её.


-----
PostgreSQL DBA
 
 Top
LIME
Отправлено: 03 Июля, 2012 - 14:44:05
Post Id


Активный участник


Покинул форум
Сообщений всего: 10732
Дата рег-ции: Нояб. 2010  


Помог: 322 раз(а)




функция в жс это тоже тип данных
поэтому можно ее присвоить
что и происходит
возвращается тип-функция
и потом ее вызываем
(Добавление)
если короче при присвоении выполняется ф-ция возвращающая ф-цию
а не запускающая ее
(Добавление)
и имя ей давать нет смысла))
во 2м варианте
 
 Top
DeepVarvar Супермодератор
Отправлено: 03 Июля, 2012 - 15:22:42
Post Id



Активный участник


Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


Помог: 353 раз(а)




Мелкий пишет:
но не вызывает её
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();
 
 Top
DlTA
Отправлено: 03 Июля, 2012 - 15:53:04
Post Id



Постоянный участник


Покинул форум
Сообщений всего: 2952
Дата рег-ции: Окт. 2010  


Помог: 53 раз(а)




JS таки удивительный язык
перепробовал
варианты: (Отобразить)

до меня наконец дошло что конструкции типа pA = function(){ return ++a;}
определяют метод, хотя это было понятно и раньше
но тогда не понятно, если взять мой первый пример
метод mvF() где относительно него хранятся свойство var pA;?
 
 Top
IllusionMH
Отправлено: 03 Июля, 2012 - 15:56:46
Post Id



Активный участник


Покинул форум
Сообщений всего: 4254
Дата рег-ции: Февр. 2011  
Откуда: .kh.ua


Помог: 242 раз(а)




Мне сейчас кажется, что все три ответа говорят об одном - происходит 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, понял тебя

(Отредактировано автором: 03 Июля, 2012 - 15:57:41)

 
 Top
DeepVarvar Супермодератор
Отправлено: 03 Июля, 2012 - 15:58:29
Post Id



Активный участник


Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


Помог: 353 раз(а)




DlTA пишет:
где относительно него хранятся свойство var pA;

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



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




DeepVarvar пишет:
Мелкий не прав.

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

vF вызывается всего 1 раз, здесь: var mvF = vF();
Затем 3 раза вызывается алерт из каллбека, который вернула функция vF. Но сама vF не вызывается.


-----
PostgreSQL DBA
 
 Top
DeepVarvar Супермодератор
Отправлено: 03 Июля, 2012 - 16:02:49
Post Id



Активный участник


Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


Помог: 353 раз(а)




Мелкий пишет:
Но сама vF не вызывается
Она по сути уже даже не нужна, т.к. выполняет роль обертки, сплюнула ссылку на а и все.
 
 Top
IllusionMH
Отправлено: 03 Июля, 2012 - 16:07:15
Post Id



Активный участник


Покинул форум
Сообщений всего: 4254
Дата рег-ции: Февр. 2011  
Откуда: .kh.ua


Помог: 242 раз(а)




DlTA пишет:
, метод mvF() где относительно него хранятся свойство var pA;?

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

(в конкретном примере это уже не происходит, но в теории)
4) если не нашли - ищем в прототипе vF
5) Снова поднимаемся вверх и т.д.

(Отредактировано автором: 03 Июля, 2012 - 16:09:56)

 
 Top
DeepVarvar Супермодератор
Отправлено: 03 Июля, 2012 - 16:16:51
Post Id



Активный участник


Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


Помог: 353 раз(а)




Упс ай, а дид ит эгейн: http://habrahabr[dot]ru/post/146784/
Хотя и говорят что не актуально уже, все-же будьте аккуратнее с этим.
 
 Top
IllusionMH
Отправлено: 03 Июля, 2012 - 16:23:25
Post Id



Активный участник


Покинул форум
Сообщений всего: 4254
Дата рег-ции: Февр. 2011  
Откуда: .kh.ua


Помог: 242 раз(а)





DeepVarvar, за ссылочку спасибо
 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« JavaScript & VBScript »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB