Особенности реализации массивов в ActionScript

Являются ли массивы ActionScript на самом деле массивами? Прежде чем ответить на этот вопрос, поставим знак тождества между понятиями «массив» и «объект». Действительно, отдельного типа данных «array» в ActionScript не существует. Массивы являются обычными объектами, и их элементы — это просто свойства, имена которых имеют вид чисел. В этой главе мы немало внимания уделили тому, чтобы показать, что между массивами и объектами не существует заметных различий.

Итак, массивы ActionScript — это обычные объекты, наследующие методы, облегчающие работу с последовательностью свойств с именами в виде целочисленных индексов. Тогда логично будет поставить следующий вопрос — а являются ли массивами объекты данных типа object?

В начале этой главы мы определили массив как объект данных, компонентами которого являются другие объекты данных. Это определение чрезвычайно обшо, и подходит оно для любого структурированного типа данных. А типов таких в теории программирования имеется немало: массивы, ассоциативные массивы, записи, списки, множества. К какому из них относятся объекты Action-Script?

Если объекты данных типа object являются по своей структуре массивами, то для них должны быть справедливы следующие утверждения:

• количество компонентов строго фиксировано и задается при создании массива;
• массив может хранить объекты данных только одного типа.


Правда, существуют еще и массивы указателей. Через элементы таких массивов можно получать доступ к объектам данных любыхтипов;
• доступ к элементам осуществляется по целочисленным индексам;
• элементы массива упорядочены, т. е. в его внутренней структуре объекту данных, доступ к которому можно получить по индексу п, предшествует объект данных, соответствующий индексу n — 1.

Ни одно из приведенных условий не выполняется в случае объектов ActionScript. Следовательно, они массивами (в классическом понимании этого термина) не являются. По этой причине сравнивать объекты класса Array с массивами универсальных языков не корректно, так как они являются принципиально различными структурами данных.
По особенностям своего поведения объекты типа object близки к записям, а еше точнее, к спискам свойств. Чем списки свойств отличаются от массивов? Во-первых, количество их компонентов не ограничено. Во-вторых, их компоненты адресуются при помощи символьных строк, а не целочисленных индексов. В-третьих, компонентами списков свойств могут быть объекты данных любых типов.

Организуются списки свойств очень просто. Они представляют собой последовательность полей, нечетные из которых сохраняют имена компонентов (в виде строк), а четные — значения компонентов.


При вызове какого-то свойства последовательно просматриваются нечетные поля до тех пор, пока нужная строка не будет найдена. Далее следует чтение ближайшего четного поля, хранящего значение свойства.

Таким образом, если объекты ActionScript являются списками свойств, то время доступа к разным свойствам должно быть различным. Чем дальше от начала списка расположено свойство, тем больше времени должно требоваться на то, чтобы найти соответствующее поле. Проверим, выполняется ли это условие:

var time:Number = null; // Переменная-таймер
var obj:Object = {}; // Создаем объект с 100000 свойствами
for (var i = 0; i<=100000; i++) {
obj [i] = 1;
time = getTimer(); // Проверяем, сколько времени понадобится
//на 50000 обращений к свойству 0
for (var j = 0; j<50000; j++) {
obj[0] = j;
trace(getTimer()-time); // Выводит: 494
time = getTimer(); // Проверяем, сколько времени понадобится на 50000
// обращений к свойству 100000
for (var k = 0; k<50000; k++) {
obj[100000] = k;
trace(getTimer()-time); // Выводит: 509

Как показано испытание, время, требующееся для доступа к свойствам объекта, физически расположенным в его разных «концах», практически идентично.


А это означает, что по своей внутренней структуре объекты записями не являются. Но к какому виду структур данных они тогда относятся?

В книге Колина Мука «ActionScript: подробное руководство» утверждается, что объекты являются ассоциативными массивами. Ввиду того, что ее научным редактором был Гари Гросман, руководитель группы, разрабатывавшей ActionScript, не доверять данной информации нет оснований.

Итак, попробуем разобраться, чем же ассоциативные массивы отличаются от обычных. Ассоциативный массив — это термин, принятый в Perl и РНР. Правильнее называть структуру данных, соответствующую объектам, множеством (set). Главной особенностью множества является то, что его компоненты абсолютно неупорядочены (компоненты списков свойств упорядочены в той последовательности, в которой они были созданы). При реализации множеств используются идеи хэш-кодирования. Поэтому их часто называют хэшами.

Скорость доступа ко всем элементам хэша одинакова. Достигается это благодаря тому, что при вызове элемента не осуществляется никакого поиска. Адресом нужного объекта данных является его имя. Дело в том, что любую строковую последовательность можно представить как число.

Опираясь на это число, можно выделить для объекта данных область памяти с определенным адресом.


Именно это и делается при создании элемента хэша. Затем, при обращении к элементу, нужно лишь повторно вычислить по переданному имени адрес в памяти, который он занимает, Функция, преобразующая строковые последовательности в адреса в хэш-таблице, называется хэш-функцией.

Таким образом, при использовании хэш-кодирования элементы множества распределяются по выделенной области памяти, в принципе, случайным образом. При этом не исключены коллизии — когда для двух разных строковых последовательностей хэш-функция выдает один и тот же адрес.

Но беспокоиться нам не о чем — технологии преодоления коллизий прекрасно отработаны. Итак, гипотеза о том, что объекты ActionScript являются хэшами, объясняет, почему время доступа к свойствам не зависит от их расположения. Хэш-кодирование требует соблюдения следующих условий:

• количество элементов множества ограничено;

• под каждый элемент множества выделяется одинаковый объем памяти. Это означает, что либо тип хранимых объектов данных должен быть одинаков, либо должны использоваться указатели.

Если при реализации объектов используется хэш-кодирование, то не совсем понятно, как работает цикл for—in.


Скорее всего, одним из атрибутов объекта является список, содержащий имена всех свойств в том порядке, в котором они создавались, Именно элементы этого списка выводятся при перечислении свойств объекта. Хотя это не более, чем предположение. Абсолютно достоверного описания особенностей реализации объектов дать невозможно, так как исходные коды Flash-плеера недоступны.

Разобравшись с тем, как устроены объекты, возвратимся к классу Array. Имеется ли какое-нибудь существенное отличие между относящимися к нему объектами и, например, объектами класса Object?

Да, оно действительно есть. Объекты класса Array используют отличный от применяемого объектами остальных встроенных классов внутренний метод, отвечающий за создание новых свойств. Главная его особенность состоит в том, что он меняет значение свойства length, если при преобразовании имени нового свойства в число его значение оказывается большим или равным величине length.

Все методы класса Array можно реализовать и самостоятельно, а вот создать код, который отвечал бы за изменение свойства length при добавлении новых элементов, документированными средствами самого ActionScript невозможно. Поэтому описанная особенность массивов как объектов является весьма сушественной.

Делаем выводы. Массивы ActionScript являются массивами лишь по форме. По своей организации они почти полностью повторяют объекты, которые в свою очередь правильнее отнести к множествам, нежели к массивам. Индексы объектов класса Array — это просто свойства, имена которых образованы символами цифр. Класс Array имитирует форму и отчасти поведение массивов таких языков, как С или Java, но относящиеся к нему объекты от этого не перестают принадлежать к типу object. Единственным заметным отличием массивов ActionScript от объектов является особый внутренний метод, меняющий свойство length при добавлении элементов.

Оцените статью: (0 голосов)
0 5 0

Статьи из раздела Action Script на эту тему:
Выделение фрагмента массива
Длина массива. Свойство length
Добавление элементов в массив
Извлечение и переопределение элементов массива
Инверсия массива

Вернуться в раздел: Action Script / 7. Массивы (класс Array)