Как мы знаем, доступ к свойствам объекта осуществляется посредством операто_ ра «точка». Доступ к свойствам объекта возможен также при помощи оператора [], который обычно применяется при работе с массивами. Таким образом, сле_ дующие два JavaScript_выражения имеют одинаковое значение:
object.property
object["property"]
Важное различие между этими двумя синтаксисами, на которое следует обратить внимание, состоит в том, что в первом варианте имя свойства представляет собой идентификатор, а во втором – строку. Скоро мы узнаем, почему это так важно.
В Java, C, C++ и подобных языках со строгой типизацией объект может иметь только фиксированное число свойств, и имена этих свойств должны быть опре_ делены заранее. Поскольку JavaScript – слабо типизированный язык, к нему данное правило неприменимо; программа может создавать любое количество свойств в любом объекте. Однако в случае использования оператора «точка» для доступа к свойству объекта имя свойства задается идентификатором. Идентифи_ каторы должны быть частью текста JavaScript_программы – они не являются типом данных и ими нельзя манипулировать из программы.
В то же время при обращении к свойству объекта с помощью нотации массивов [] имя свойства задается в виде строки. Строки в JavaScript – это тип данных, поэтому они могут создаваться и изменяться во время работы программы. И по_ этому в JavaScript можно, например, написать следующий код:
var addr = "";
for(i = 0; i < 4; i++) {
addr += customer["address" + i] + '\n';
}
В этом фрагменте читаются и объединяются в одну строку свойства address0, add_ ress1, address2 и address3 объекта customer.
126 Глава 7. Объекты и массивы
Этот короткий пример демонстрирует гибкость нотации массивов при обраще_ нии к свойствам объекта с помощью строковых выражений. Мы могли бы напи_ сать этот пример и с помощью оператора «точка», но есть ситуации, где подой_ дет только нотация массивов. Предположим, что вы пишете программу, обра_ щающуюся к сетевым ресурсам для вычисления текущей суммы инвестиций пользователя на фондовом рынке. Программа разрешает пользователю вводить названия любых имеющихся у него акций, а также количество каждого вида ак_ ций. Можно организовать хранение этой информации при помощи объекта с именем portfolio, имеющего по одному свойству для акций каждого вида. Имя свойства – это название акции, а значение свойства – количество акций данного вида. Другими словами, если, например, у пользователя имеется 50 акций IBM, то свойство portfolio.ibm имеет значение 50.
Частью этой программы должен быть цикл, запрашивающий у пользователя на_ звание имеющихся у него акций, а затем количество акций данного типа. Внут_ ри цикла должен быть код, похожий на следующий:
var stock_name = get_stock_name_from_user(); var shares = get_number_of_shares(); portfolio[stock_name] = shares;
Поскольку пользователь вводит названия акций во время исполнения програм_ мы, нет способа узнать имена свойств заранее. А раз имена свойств при написа_ нии программы неизвестны, то доступ к свойствам объекта portfolio при помо_ щи оператора «точка» невозможен. Однако можно обратиться к оператору [], т. к. в нем для имени свойства используется строковое значение (которое может изменяться во время выполнения), а не идентификатор (который должен быть задан непосредственно в тексте программы).
Когда объект используется в такой форме, его часто называют ассоциативным массивом – структурой данных, позволяющей связывать произвольные значе_ния с произвольными строками. Нередко для описания этой ситуации использу_ ется термин отображение (map): JavaScript_объекты отображают строки (имена свойств) на их значения.
Использование точки (.) для доступа к свойствам делает их похожими на стати_ ческие объекты в языках C++ и Java, и они прекрасно работают в этой роли. Но они также предоставляют мощное средство для связи значений с произвольны_ ми строками. В этом отношении JavaScript_объекты значительно больше похо_ жи на массивы в Perl, чем на объекты в C++ или Java.
В главе 6 был введен цикл for/in. Настоящая мощь этой JavaScript_конструкции становится понятной при ее использовании с ассоциативными массивами. Воз_ вращаясь к примеру с портфелем акций, после ввода пользователем данных по своему портфелю вычислить текущую общую стоимость последнего можно при помощи следующего кода:
var value = 0;
for (stock in portfolio) {
// Для каждого вида акций в портфеле получаем стоимость
// одной акции и умножаем ее на число акций.
value += get_share_value(stock) * portfolio[stock];
}
7.4. Свойства и методы универсального класса Object
Здесь не обойтись без цикла for/in, поскольку названия акций заранее неизвест_ ны. Это единственный способ извлечения имен этих свойств из ассоциативного массива (JavaScript_объекта) по имени portfolio.