Беларусь, рогачёв |
Функции
Локальные переменные
Локальные переменные нужны не только в языках программирования общего назначения, но и во Флэш МХ. Чтобы убедиться в этом, достаточно рассмотреть следующий пример:
function progressionSum(low, hi, step){ for (i=low; i<=hi; i+=step) sum+=i; // Здесь нарочно не пишем var как будто бы мы не знаем, что это return sum; } // Используем нашу функцию trace("sum = " + progressionSum(4, 10, 3)); //Вроде бы делаем то же самое trace("sum = " + progressionSum(4, 10, 3));
Этот код выводит следующее:
sum = 21 sum = 42
То есть программист, решивший положиться на то, что Флэш сам заводит переменную, если в нее хотят что-то записать (и при этом делает ее равной нулю), должен хорошо представлять себе, где именно Флэш эту переменную заведет. В данном случае было заведено поле в том клипе, в котором определена функция progressionSum (и, конечно, записанное в нем значение сохранилось до следующего вызова). Так что локальные переменные нужны. И для того чтобы такую переменную создать, необходимо использовать ключевое слово var. В результате заводится обычная флэш-переменная, только теперь объект, в котором она лежит - это контекст вызова функции. (Далее мы увидим, что до этого объекта можно хитрым образом добраться "снаружи" - но это далеко не типичное использование локальной переменной. А типичное, хотя оно и очевидно, на всякий случай описано далее.)
Типичный пример использования
Вот исправленный пример функции progressionSum:
function progressionSum(low, hi, step){ var sum; for (i=low; i<=hi; i+=step) sum+=i; return sum; } trace("sum = " + progressionSum(4, 10, 3)); trace("sum = " + progressionSum(4, 10, 3));
На сей раз мы получаем
sum = 21 sum = 21
как того и следовало ожидать. (В этом варианте функции все еще есть одна погрешность, которую мы исправим позднее. Можете пока ее поискать.)
Локальные переменные бывают только в функциях
Однако не следует думать, что с локальными переменными все так же хорошо, как в С++. Во-первых, в С++ на локальность переменных влияют вложенные блоки (и переменная, заведенная внутри блока, видна только внутри него). Этого свойства нет даже в Java! Что уж говорить о Флэше. Но даже если мы объявим локальную переменную просто в кадре какого-либо клипа, мы на деле заведем в этом клипе обычное поле (то есть ключевое слово var будет попросту проигнорировано). Точнее, все будет именно так, если код в кадре выполняется обычным образом - в тот момент, когда до этого кадра дошла очередь в линейке времени. Если же код из кадра был вызван при помощи команды Call (не путайте с методом Function.call, о котором далее), то переменная, объявленная с помощью var все-таки будет локальной. Но для нас подобные ухищрения не имеют особого смысла, поскольку гораздо проще и понятнее создать отдельную функцию, чем вызывать код из какого-то кадра командой Call. Мы ведь уже говорили, что, в отличие от метода Function.call, команда Call - это типичный атавизм.
Итак, смысл локальной переменной во Флэше - это переменная, видимая только внутри данной функции . С другой стороны, поскольку переменные во Флэше могут быть заведены автоматически в момент использования - постарайтесь при определении функций ставить var везде, где только возможно (чтобы не засорять пространство имен объемлющего объекта). Например, в функции progressionSum из предыдущего примера все же была допущена ошибка, в чем мы убедимся, запустив такой код:
for (i=0; i<4; i++) trace("i = " + i + "; sum = " + progressionSum(i, 10, 3));
В результате мы получим
i = 0; sum = 18
- всего одну строчку, хотя ожидали получить четыре. Ошибка, разумеется, в том, что в цикле for внутри функции мы использовали то же имя переменной, что и снаружи, а вот о том, чтобы сделать переменную локальной, не позаботились.
Так что следовало написать:
function progressionSum(low, hi, step){ var sum; for (var i=low; i<=hi; i+=step) sum+=i; return sum; } for (i=0; i<4; i++) trace("i = " + i + "; sum = " + progressionSum(i, 10, 3));
и тогда мы получим
i = 0; sum = 18 i = 1; sum = 22 i = 2; sum = 15 i = 3; sum = 18
Хотелось бы, конечно, сделать и внешнюю переменную i локальной внутри своего цикла, но, к сожалению, это невозможно. Локальной внутри цикла (блока) переменная во Флэш МХ не бывает. Только внутри функции.