Казахстан, Алматы, Гимназия им. Ахмета Байтурсынова №139, 2008 |
Контейнеры
Эмуляция хэш-таблицы при помощи объекта
Мы уже знаем, что можно обращаться к полям объекта удобным, но недокументированным способом - при помощи квадратных скобок. Нужно только иметь имя этого поля в виде строки - чем не хэш-таблица? Можно в качестве имени даже передать число - оно будет преобразовано в строку:
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 ).