Содержание
Стандарты Actionscript
Приложения Macromedia Flash в основном строились без учета каких-либо стандартов
и основополагающих принципов. Такая гибкость способствует решению задач множеством
способов, и это хорошо, но приложение становится непроходимым лесом для всех кроме
автора — такой код сложен для понимания. Даже автор, спустя некоторое
время, будет с трудом читать написанный им же код. Если разработчик не может понять
код в приложении, то код будет трудно отлаживать, вносить в него изменения или
использовать его многократно.
Стиль ![Наверх](../../i/link_top.gif)
Принципы присвоения имен ![Наверх](../../i/link_top.gif)
Во-первых, схема присвоения имен должна быть последовательной, а имена должны
быть удобными для чтения и понимания. Это означает, что имена должны быть понятными
словами или фразами. Первичная функция или назначение любого объекта должны быть
очевидными из его имени. Так как типы переменных в ActionScript контролируются
динамически, то имя должно также содержать суффикс, определяющий тип объекта,
на который ссылается имя. Самый естественный случай имен — это фразы
типа "существительное-глагол" или "прилагательное-существительное". Например:
- Имя клипа — "my_movie.swf";
- Переменная для добавления к URL — "course_list_output" (вывод
списка курсов);
- Компонент или объект — "ProductInformation" (информация о
продукте)
- Переменная или свойство — "userName" (имя пользователя)
Имена функций и переменных должны начинаться со строчной буквы (a, b, c, ...,
x, y, z). Имена объектов и конструкторов объектов должны начинаться с заглавной
буквы (A, B, C, ..., X, Y, Z). Использование смешанных регистров символов рекомендуется
в случае именования переменных. Другие форматы именования приемлемы, если они
используются последовательно во всем проекте. Имя переменной может содержать только
буквы, числа и символы подчеркивания. Не начинайте имя переменной с числа или
символа подчеркивания. Неправильными именами переменных будут следующие:
- _count = 5; // начинается с символа подчеркивания
- 5count = 0; // начинается с числа
- foo/bar = true; // содержит символ "слэш"
- foo bar = false; // содержит пробел
Кроме того, в качестве имен переменных нельзя использовать ключевые слова ActionScript.
Также избегайте использования в качестве имен переменных слов из популярных конструкций
программирования, даже если Macromedia Flash Player к настоящему времени не поддерживает
эти конструкции в качестве ключевых слов. Это дает больше уверенности в том, что
будущие версии проигрывателя не вступят в конфликт с вашим приложением. Например,
не нужно делать так:
- var = "foo";
- MovieClip = "myMovieClip";
- switch = "on";
- case = false;
- abstract = "bar";
- extends = true;
- implements = 5;
Так как ActionScript совместим с ECMAScript, авторы приложений могут ознакомиться
со списком зарезервированных слов, приведенных в
спецификации ECMA. Пока Flash MX не поддерживает константы, разработчики
должны применять следующий принцип: имена переменных набирать символами нижнего
регистра, а имена переменных-констант — только символами верхнего регистра.
Например:
- course_list_output = "foo"; // переменная
- courseListOutput = "foo"; // переменная
- BASEURL = http://www.foo.com; // константа
- MAXCOUNTLIMIT = 10; // константа
- MyObject = function{}; // функция конструктора
- f = new MyObject(); // объект
Редактор кода ActionScript в среде разработки Flash MX имеет встроенную
функцию "завершения кода". Эта функция помогает вам писать код, предоставляя
в виде выпадающего списка возможные варианты завершения кода. Чтобы вы могли пользоваться
этим преимуществом, имена ваших переменных должны соответствовать определенному
формату. В этом встроенном формате суффикс имени переменной является строкой,
указывающей на тип переменной. Ниже приведена таблица поддерживаемых суффиксов:
Таблица 3: Суффиксы для активации функции завершения кода
Тип объекта |
Суффикс |
Пример |
String |
_str |
myString_str |
Array |
_array |
myArray_array |
MovieClip |
_mc |
myMovieClip_mc |
TextField |
_txt |
myTextField_txt |
Date |
_date |
myDate_date |
Sound |
_sound |
mySound_sound |
XML |
_xml |
myXML_xml |
Color |
_color |
myColor_color |
Button[1] |
_btn |
myButton_btn |
TextFormat |
_fmt |
myTextFormat_fmt |
XMLSocket |
_xmlsocket |
myXmlSocket_xmlsocket |
FListBox |
_lb |
myFListBox_lb |
FScrollBar |
_sb |
myFScrollBar_sb |
FComboBox |
_cb |
myFComboBox_cb |
FScrollPane |
_sp |
myFScrollPane_sp |
FMessageBox[2] |
_mb |
myFMessageBox_mb |
FDraggablePane |
_dp |
myFDraggablePane_dp |
FTicker |
tick_ (префикс) |
tick_myFTickerMain |
FTree |
_tree |
myFTree_tree |
FTreeNode |
_tn |
myFTreeNode_tn |
FIconButton |
_ib |
myFIconButton_ib |
FProgressBar |
_pr |
myFProgressBar_pr |
|
Вы увидите эту функцию в действии, если наберете в панели Actions один из примеров
и символ точки. Например, введите myString_str.
— появится
выпадающий список свойств и методов для объекта String
. Не забывайте
о точке:
![Рисунок 1: Пример действия помощника завершения кода](codecomplete.gif)
Рисунок 1: Пример действия помощника завершения кода.
Наконец, имена всех .swf-файлов должны быть набраны в нижнем регистре, а слова
в именах должны быть разделены символом подчеркивания (например, "lower_case.swf").
Обсуждение соглашений об именовании включаемых файлов ActionScript см. в разделе
"Используйте файлы #include .as".
Помните, что вышеуказанные рекомендации являются общими принципами. Важнее
всего, выбрав определенную схему именования, использовать ее последовательно во
всем приложении или проекте.
Комментирование кода ![Наверх](../../i/link_top.gif)
Комментируйте код всегда. Для разработчика комментарии являются хорошей возможностью
рассказать, для чего написан код и что он должен делать. Комментарии должны подтверждать
каждое решение — в любом месте, в котором вы производили выбор и принимали
решение о способе кодирования, нужно вставлять комментарий с обоснованием сделанного
выбора.
Когда вы пишете "обходной" код для решения специфических, нестандартных
задач вашего приложения, добавьте комментарий, из которого другие разработчики
поймут, в чем заключалась сложность, и как вы ее обошли. Это облегчает понимание
специфических проблем теми разработчиками, которые еще могут с ними столкнуться.
Это просто облегчает им жизнь.
Вот пример простого комментария для переменной:
var clicks = 0; // переменная для подсчета нажатий кнопки
Блочные комментарии полезны для больших кусков текста:
/*
Инициализирует переменную clicks
, хранящую количество нажатий кнопки.
*/
Ниже приведены некоторые общие методы для указания особо важных комментариев
(в скобках предложены русскоязычные аналоги):
// :TODO: topic (// :СДЕЛАТЬ: тема)
Указывает, что код нужно доделать или сделать что-то еще.
// :BUG: [bugid] topic (// :ОШИБКА: [номер ошибки] тема)
Показывает известную ошибку ("глюк", "баг"). Комментарий
также должен объяснять, в чем состоит проблема, и содержать "bug ID
"
(номер "бага"), если необходимо.
// :KLUDGE: (// :ВОЗМОЖЕН ДРУГОЙ ВАРИАНТ:)
Показывает, что соответствующий код не является элегантным или лучшим решением.
Этот комментарий оповещает других, что в будущем код следует усовершенствовать.
// :TRICKY: (// :РИСКОВАНО:)
Уведомляет разработчиков, что код со многим взаимосвязан (его изменение повлечет
изменения в других местах). Это совет разработчику: "подумай, прежде чем
что-то изменять".
Пример
/*
:TODO: msw 654321: проблемы с отображением больших объемов данных из БД. Наверное,
следует разбивать данные на более мелкие порции для каждого запроса.
*/
Формат
временной диаграммы (таймлайна) ![Наверх](../../i/link_top.gif)
Избегайте использования названий слоев, принятых по умолчанию (Layer 1
,
Layer 2
, и т.п.), так как это может привести к путанице. Слои
таймлайна должны называться интуитивно понятным образом. Слои также должны быть
сгруппированы вместе путем использования папок там, где это имеет смысл. Например,
следует располагать все слои с кодом ActionScript на самом верху стека слоев,
чтобы в таймлайне можно было легко найти весь код.
Блокирование неиспользуемых в данный момент слоев — хорошая практика.
Это предупреждает случайные изменения в документе.
Область видимости ![Наверх](../../i/link_top.gif)
Flash Player 6 поддерживает концепцию "цепочки областей видимости"
(как определено в стандарте ECMA-262). Таким образом, устранены значительные
недостатки "прямой области видимости" в Flash Player 5.
Цепочка областей видимости — это список ActionScript-объектов. Flash Player
ищет идентификатор, начиная с последнего элемента в цепочке областей видимости,
и продолжает подниматься по цепочке, пока не найдет его.
Цепочка областей видимости для типичного сценария ActionScript:
- Объект
Global
;
- Объект
MovieClip
;
- Локальные переменные.
Конструкция with
временно добавляет объект в конец цепочки областей
видимости. Когда действие with
прекращается, объект удаляется из
цепочки областей видимости.
При определении функции текущая цепочка областей видимости копируется и хранится
в объекте функции. При вызове функции происходит переключение текущей цепочки
областей видимости на цепочку областей видимости объекта функции, а в конец цепочки
добавляется новый объект Local Variables.
В Flash 5 область видимости функции всегда была следующей:
- Объект
Global
;
- мувиклип, содержащий функцию;
- Локальные переменные.
Список областей видимости никогда не содержал более трех пунктов, кроме случая
с использованием with
. Это было отклонением от стандарта ECMA-262,
и область видимости метода всегда находилась в мувиклипе, содержащем метод, а
не в месте определения этого метода.
В Macromedia Flash Player 6 при определении метода мувиклипа вне самого мувиклипа
цепочка областей видимости метода будет содержать внешний объект, а не объект
мувиклипа, для которого определяется метод. В таком случае в теле определяемого
метода необходимо использовать ключевое слово this
, чтобы используемые
в этом методе идентификаторы ссылались на объект мувиклипа, а не на внешний объект.
Имейте в виду, что поддерживается обратная совместимость с Flash Player 5.
Для среды разработки Flash 5 применимы те же правила использования области
видимости, что и для Flash Player 5.
Используйте относительные
пути для задания области видимости ![Наверх](../../i/link_top.gif)
Область видимости должна быть задана для каждой переменной. Исключением являются
параметры функций и локальные переменные. Область видимости переменных должна
задаваться относительно их текущего положения, если это возможно. Использование
_root
для задания области видимости переменной не рекомендуется,
поскольку это ограничивает мобильность кода. Вместо _root
используйте
ключевое слово _parent
или this
, например:
this.myVar.blah = 100; // определяйте область видимости для
переменных, используя относительную адресацию, как в этой строке
_root.myMovieClip.myVar.blah = 100; // НЕ задавайте область видимости переменных,
используя абсолютные ссылки, как в этой строке
Если все же приходится использовать абсолютную адресацию к главному таймлайну,
вместо использования _root
создайте переменную-ссылку на главный
таймлайн. Это позволит изменять всего один параметр, если структура таймлайна
изменится. Чтобы создать удобную ссылку на основной таймлайн клипа, добавьте такую
строку кода к основному таймлайну:
_global.myAppMain = this; // (замените "myApp" названием
вашего приложения)
После вставки этой строки в ваше приложение, используйте _global.myAppMain.someFunction
,
чтобы ссылаться на функции главного таймлайна. Это позволяет изменять структуру
приложения, не нарушая область видимости вызовов функций и переменных в клипе.
_root против _global ![Наверх](../../i/link_top.gif)
Важно понимать разницу между _global
и _root
. Ссылка
_root
уникальна только в рамках каждого загруженного .swf-клипа.
Ссылка _global
применима ко всем клипам в пределах проигрывателя.
В общем случае для ссылок лучше использовать _global
, а не _root
.
Соглашения ActionScript ![Наверх](../../i/link_top.gif)
Держите весь код в одном месте ![Наверх](../../i/link_top.gif)
Везде, где это возможно, весь код должен размещаться в одном месте. Это облегчает
его нахождение и отладку. Одна из главных сложностей в отладке клипов Macromedia
Flash — это поиск кода. Если большая часть кода размещена в одном кадре,
эта проблема устраняется. Обычно лучшее место для размещения кода — это
первый кадр.
Когда в первом кадре расположен большой код, разделите его на части комментариями,
чтобы повысить читабельность, например:
/*** Раздел функций для кнопок ***/
/*** Константы и переменные ***/
Одно исключение при размещении всего кода в первом кадре возникает в случае
предварительной загрузки клипов. В приложении с предзагрузкой клипов размещение
всего кода в первом кадре может быть невозможным. Но все равно нужно стремиться
к централизации кода.
В клипах с прелоадером начинайте написание кода со второго кадра. Используйте
два слоя для кода — один слой для функций, а другой слой для действий, связанных
с различными состояниями приложения.
Помните, что функции и объекты, созданные программными методами ActionScript,
существуют на протяжении всего клипа. Вместе с этим продолжает действовать механизм
создания и уничтожения мувиклипов, базирующийся на состояниях временной диаграммы.
Временная диаграмма должна отражать эту взаимосвязь.
![Рисунок 2: Пример временной диаграммы с предзагрузчиком](timeline.gif)
Рисунок 2: Пример временной диаграммы ("таймлайна") с предзагрузчиком.
Используйте файлы #include .as ![Наверх](../../i/link_top.gif)
Любой определенный вами объект или библиотека созданных вами функций должны
определяться во внешнем ActionScript файле и использоваться в качестве файла включаемого
(include) файла. Например, если приложение использует объекты с именами "Foo"
и "Bar", каждый из этих объектов должен содержаться в отдельном включаемом
ActionScript-файле. Имя включаемого файла должно соответствовать имени объекта,
например:
Foo.as
Bar.as
Библиотеки многократно используемых функций должны также определяться во включаемых
файлах ActionScript. В этом случае имя включаемого файла должно состоять из букв
нижнего и верхнего регистра (начинаясь с буквы нижнего регистра), например:
stringUtils.as
Такая система использования включаемых файлов делает объектно-ориентированный
код ActionScript более легким для идентификации. Но более важно то, что код становится
модульным, позволяя разработчикам создавать ActionScript-библиотеки объектов и
функций. Только необходимый для приложения код включается из библиотеки внешних
файлов.
Кроме того, используя внешние файлы ActionScript, разработчики могут интегрировать
файлы кода с системой управления версиями, например, такими, CVS или SourceSafe.
Это облегчает отслеживание исходного кода.
Кадры как состояния приложения ![Наверх](../../i/link_top.gif)
Разработчики часто пишут построчный код (программу) прямо на отдельных кадрах,
чтобы определять состояния приложения. Такая практика нежелательна.
Правильная организация кода базируется на описании состояний приложения в
ключевых кадрах. Поместите в функцию любое действие, необходимое для конкретного
состояния, а затем вызывайте эту функцию как единственное действие в соответствующем
ключевом кадре.
Продолжая организацию приложения, создайте в клипе два слоя с кодом. В первом
кадре первого слоя, существующего по всей длине клипа, располагается самая большая
часть кода. Второй слой содержит действия, необходимые ключевым кадрам для изменения
состояний приложения. Единственный код в каждом ключевом кадре второго слоя должен
быть вызовом функции для конкретного состояния (вызываемая функция должна быть
описана в первом кадре первого слоя). Для создания некоторых состояний (например,
для вызовов диалоговых окон) допускается использование мувиклипов, присоединенных
с помощью действия attachMovie
во время выполнения приложения.
Избегайте размещения кода на
мувиклипах и кнопках ![Наверх](../../i/link_top.gif)
Не размещайте код на мувиклипах и кнопках, если в этом нет крайней необходимости.
Если код все же должен быть размещен на мувиклипе или кнопке, используйте при
этом минимальное количество кода. С этой точки зрения лучше всего вызывать функции,
как в следующем примере:
myButton.onMouseDown = function() {
_parent.doMouseDown(this);
}
Использование вызова функции переносит всю функциональность на основной таймлайн
мувиклипа.
Инициализация ![Наверх](../../i/link_top.gif)
Инициализация приложения используется для задания его начального состояния.
Функция инициализации вызывается в приложении в первую очередь и только один раз —
программой. Все остальные вызовы этой функции должны управляться событиями.
// кадр 1
this.init();
function init() {
if (this.inited != undefined)
return;
this.inited = true;
// здесь идет код инициализации...
}
Используйте ключевое слово
var
для локальных переменных ![Наверх](../../i/link_top.gif)
Все локальные переменные должны использовать ключевое слово var
.
Это предохраняет переменные от глобального доступа и, что более важно, предохраняет
переменные от неумышленного переназначения[3].
Например, следующий код функции не использует ключевое слово var
при объявлении переменной, что приводит к (неумышленной) перезаписи внешней переменной,
не относящейся к функции:
counter = 7;
function loopTest()
{
trace(counter);
for(counter = 0; counter < 5; counter++)
{
trace(counter);
}
}
trace(counter);
loopTest();
trace(counter);
Этот код выводит:
7
7
0
1
2
3
4
5
В данном случае переменная counter
, находящаяся на основной временной
диаграмме, переназначается переменной counter
, которая находится
внутри функции. Ниже приведен исправленный код, который использует ключевое слово
var
, для объявления обеих переменных. Использование декларации var
в функции устраняет ошибку вышеуказанного кода:
var counter = 7;
function loopTest()
{
trace(counter);
for(var counter = 0; counter < 5; counter++)
{
trace(counter);
}
}
trace(counter);
loopTest();
trace(counter);
Исправленный код выводит следующее:
7
7
0
1
2
3
4
7
Из последней строки видно, что не принадлежащая функции переменная counter
сохранила свое значение после вызова функции.
Создание объектов ![Наверх](../../i/link_top.gif)
При создании объекта включайте в его прототип функции и свойства, распространяемые
на все экземпляры объекта. Это гарантирует, что в оперативной памяти будет находиться
только одна копия каждой функции. Сделайте своим правилом не определять функции
внутри конструктора — это создает для каждого экземпляра объекта отдельную
копию этой же функции и приводит к излишнему расходованию оперативной памяти.
Пример лучшей практики создания объекта:
MyObject = function()
{
}
MyObject.prototype.name = "";
MyObject.prototype.setName = function(name)
{
this.name = name;
}
MyObject.prototype.getName = function()
{
return this.name;
}
Следующий пример демонстрирует неправильный метод создания объекта:
MyObject = function()
{
this.name = "";
this.setName = function(name)
{
this.name = name;
}
this.getName = function()
{
return this.name;
}
}
В первом примере каждый экземпляр объекта MyObject
указывает на
одни те же функции и свойства, определенные в прототипе объекта. При этом в оперативной
памяти находится только одна копия getName()
, независимо от количества
созданных объектов MyObject
.
Во втором примере каждый созданный экземпляр MyObject
создает
копию каждого свойства и функции. Эти дополнительные свойства и функции занимают
дополнительную память, и в большинстве случаев не предоставляют при этом никаких
преимуществ.
Наследование объектов ![Наверх](../../i/link_top.gif)
Задание свойства "__proto__
" для создания наследования
практиковалось в Flash Player 5. Эта практика не поддерживается
в Flash Player 6, и ее использование не рекомендуется.
Свойство __proto__
должно рассматриваться как свойство только для
чтения (read-only). Правильный способ создания наследования — это создание
цепочки прототипов. Чтобы создать цепочку прототипов, установите свойство "prototype
"
функции конструктора подкласса (subclass) в экземпляр надкласса (superclass),
используя следующий синтаксис:
ChildClass.prototype = new ParentClass();
Пример этой практики:
function Shape()
{
}
function Rectangle()
{
}
Rectangle.prototype = new Shape();
Следующая практика НЕ рекомендуется:
Rectangle.prototype.__proto__ = Shape.prototype;
Если разработчики беспокоятся, что такая форма наследования приведет к тому,
что весь конструктор будет признан необязательным, следующий код поможет предотвратить
это:
_global.SuperClassConstructor = function() {
if (this._name!=undefined) {
// код конструктора размещается
здесь
}
}
В вышеприведенном примере код конструктора не будет выполнен, потому что еще
не определен экземпляр. Заметьте, что этот код работает только в классах, основанных
на классе MovieClip.
Производительность ![Наверх](../../i/link_top.gif)
Предварительная загрузка ![Наверх](../../i/link_top.gif)
Главная проблема создания компонентов, хорошо согласовывающихся с процессом
предварительной загрузки — это минимизация количества объектов, загружающихся
перед первым кадром. Символы в первом кадре загружаются прежде, чем в проигрывателе
сможет отобразиться какая-либо графика. Это означает, что даже компонент прелоадера
не появится, пока не будут загружены все символы с пометкой "Export in First
Frame" (экспортировать в первом кадре). Поэтому любой код ActionScript, обрабатывающий
действия пользователя, должен всегда помещаться в кадре, следующем после кадра
с прелоадером.
Типы данных и их размеры в файлах
.swf
Следующая информация может использоваться для оптимизации времени загрузки
критических частей приложения.
Таблица 2: Основные объекты ActionScript
Тип объекта |
Размер, байтов |
Короткая строка (7 символов) |
55 |
Число |
22 |
Объект |
340 |
Пустой мувиклип |
800 |
Объект функция |
700 |
Текстовое поле |
9 500 |
|
Таблица 3: Простые .swf-файлы
Тип простого .swf-файла |
Размер, байтов |
Пустой .swf-файл |
250 000 (большая часть памяти уходит на встроенные объекты ActionScript) |
Пустой .swf-файл с определенным компонентом |
750 000 (большая часть отводится самому .swf-файлу и объекту функции компонента) |
|
Таблица 4: Объекты компонентов (по одному экземпляру)
Объект компонента |
Размер, байтов |
PushButton |
60 000 |
CheckBox |
55 000 |
Пустой ListBox |
490 000 |
|
Предосторожности использования
оперативной памяти ![Наверх](../../i/link_top.gif)
Текст. Каждый отдельный текстовый объект использует 10 КБ
памяти. Это относится к динамическим текстовым полям, полям для ввода текста и
статическим текстовым полям, использующим шрифты устройств ("device fonts"),
например, "_sans".
Мувиклип. Каждый мувиклип использует около 1 КБ памяти. Это
число может стремительно возрастать при увеличении количества используемых мувиклипов.
Имейте в виду, что графические символы (graphic) не обладают такими высокими требованиями
к памяти, как мувиклипы.
Объекты функций. Каждый объект функции создает два объекта
ActionScript, вместе занимающие 700 байтов. Создание объекта функции для каждого
экземпляра объекта — дорогое удовольствие с точки зрения расхода памяти.
Рекомендуется всегда использовать прототипы. Прототипы создаются только один раз
и помогают избежать неоправданного расходования памяти.
Вывод ![Наверх](../../i/link_top.gif)
Этот документ не является завершенным набором лучших методов создания кода.
Macromedia продолжает расширение документа, основываясь на информации от людей,
создающих и продвигающих критически важные по своему значению приложения для Flash Player.
Этот документ живой, он управляется сообществом разработчиков, как это всегда
было с ActionScript и Macromedia Flash Player с самого начала их существования.
оригинал: Macromedia
перевод: Флэш-потрошитель
рецензент: fix