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

Контейнеры

Эмуляция хэш-таблицы при помощи объекта

Мы уже знаем, что можно обращаться к полям объекта удобным, но недокументированным способом - при помощи квадратных скобок. Нужно только иметь имя этого поля в виде строки - чем не хэш-таблица? Можно в качестве имени даже передать число - оно будет преобразовано в строку:

obj1 = {};
obj1["aaa"] = 1;
obj1["bbb"] = 2;
obj1[4] = 1000;
obj1[4.00001e-17] = 1000000;
obj1["!@#$%%^&*()_):"] = 222;
trace(obj1["bb" + "b"]);
trace(obj1[10*(4 + 0.00001)/1e18]);
trace(obj1["!@#$%%^&*()_):"]);

Запустив это, на выходе получаем

2
1000000
222

А теперь давайте скомандуем List Variables ( Ctrl+Alt+V ). Результат:

Level #0:
Variable _level0.$version = "WIN 6,0,21,0"
Variable _level0.obj1 = [object #1, class 'Object'] {
 aaa:1,
 bbb:2,
 4:1000,
 4.00001e-17:1000000,
 !@#$%%^&*()_)::222
}

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

Как Флэш трактует "смешанный массив" (с числовыми и нечисловыми ключами)

Давайте для разрешения этих вопросов сделаем такой "смешанный" массив и произведем с ним различные действия.

a_array = [23, 45, 67, 88];
a_array["kk"] = 345;
a_array[-1] = 3333333;
a_array.push(100);
trace("a_array: " + a_array);
trace("a_array.length: " + a_array.length);
   // Выводим кусок побольше, чтобы посмотреть, не прячется ли
   // что-то за дальней границей массива
trace("a_array.slice(2,6): " + a_array.slice(2,6));
trace("----- Names -----");
for(var name in a_array) trace(name);
trace("----------------");

trace(a_array["kk"]);

Вот что выводит этот код:

a_array: 23,45,67,88,100
a_array.length: 5
a_array.slice(2,6): 67,88,100
----- Names -----
4
-1
kk
3
2
1
0
----------------
345

А вот что мы получаем после команды List Variables

Level #0:
Variable _level0.$version = "WIN 6,0,21,0"
Variable _level0.a_array = [object #1, class 'Array'] [
  0:23,
  1:45,
  2:67,
  3:88,
  4:100,
  kk:345,
  -1:3333333
 ]
Variable _level0.name = "0"

В результате можно сделать следующие выводы. Массив, как и обычный объект, на деле представляет собой хэш-таблицу. И с точки зрения того, как хранится информация, все ключи в этой таблице равноправны. Однако, когда мы начинаем с этой информацией работать, а именно, пользоваться специфичными для массива методами (например, сортировкой ), то учитываются только ключи, являющиеся целыми неотрицательными числами. И даже длина массива (поле length ) корректируется только с учетом таких ключей. Так что достать из массива данные по ключу, не являющемуся целым неотрицательным числом, можно лишь, обратившись к ним напрямую. (Зато если ключ является допустимым именем переменной, как, например, kk в вышеприведенном коде, то обращаться к хранящейся по этому ключу информации можно и через точку: a_array.kk ).