Московский физико-технический институт
Опубликован: 23.12.2005 | Доступ: свободный | Студентов: 2869 / 253 | Оценка: 4.61 / 4.44 | Длительность: 27:18:00
ISBN: 978-5-9556-0051-2
Лекция 5:

Функции

Локальные переменные

Локальные переменные нужны не только в языках программирования общего назначения, но и во Флэш МХ. Чтобы убедиться в этом, достаточно рассмотреть следующий пример:

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 локальной внутри своего цикла, но, к сожалению, это невозможно. Локальной внутри цикла (блока) переменная во Флэш МХ не бывает. Только внутри функции.