Чтение онлайн

ЖАНРЫ

JavaScript. Подробное руководство, 6-е издание
Шрифт:

Выше уже говорилось, что при использовании формы записи с квадратными скобками выражение в скобках должно возвращать строку. Если быть более точными, это выражение должно возвращать строку или значение, которое может быть преобразовано в строку. В главе 7, например, мы увидим распространенный прием использования чисел в квадратных скобках.

6.2.1. Объекты как ассоциативные массивы

Как отмечалось выше, следующие два выражения возвращают одно и то же значение:

object.property

object["property"]

Первая форма записи, с использованием точки и идентификатора,

напоминает синтаксис доступа к статическому полю структуры или объекта в языке С или Java. Вторая форма записи, с использованием квадратных скобок и строки, выглядит как обращение к элементу массива, но массива, который индексируется строками, а не числами. Такого рода массивы называются ассоциативными массивами (а также хешами и словарями). Объекты в языке JavaScript являются ассоциативными массивами, и в этом разделе объясняется, почему это так важно.

В С, C++, Java и других языках программирования со строгим контролем типов объект может иметь только фиксированное число свойств, а имена этих свойств должны определяться заранее. Поскольку JavaScript относится к языкам программирования со слабым контролем типов, данное правило в нем не действует: программы могут создавать любое количество свойств в любых объектах. Однако при использовании для обращения к свойству оператора точка (

.
) имя свойства определяется идентификатором. Идентификаторы должны вводиться в тексте программы буквально - это не тип данных, поэтому в программе невозможно реализовать вычисление идентификаторов.

Напротив, когда для обращения к свойствам объекта используется форма записи с квадратными скобками (

[]
), имя свойства определяется строкой. Строки в языке JavaScript являются типом данных, поэтому они могут создаваться и изменяться в ходе выполнения программы. Благодаря этому, например, в языке JavaScript имеется возможность писать такой программный код:

var addr = "";

for(i =0; і < 4; і++)

addr += customer["address" + і] + ‘\n';

Этот фрагмент читает и объединяет в одну строку значения свойств address0, address1, address2 и address3 объекта customer.

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

portfolio
. Объект имеет по одному свойству для каждой компании. Имя свойства одновременно является названием компании, а значение свойства определяет количество акций этой компании. То есть если, к примеру, пользователь владеет 50 акциями компании IBM, свойство
portfolio.ibm
будет иметь значение 50.

Следующая функция, добавляющая информацию об очередном пакете акций, могла бы быть частью такой программы:

function addstock(portfolio, stockname, shares) {

portfolio[stockname] = shares;

}

Поскольку пользователь вводит имена компаний во время выполнения, нет никакого способа заранее определить эти имена. А так как на момент создания программы имена свойств нам неизвестны, мы не можем использовать оператор точки (

.
) для доступа к свойствам объекта
portfolio
.
Однако мы можем задействовать оператор
[]
, потому что для обращения к свойствам он позволяет использовать строковые значения (которые являются динамическими и могут изменяться во время выполнения) вместо идентификаторов (которые являются статическими и должны жестко определяться в тексте программы).

В главе 5 был представлен цикл

for/in
(и еще раз мы встретимся с ним чуть ниже, в разделе 6.5). Мощь этой инструкции языка JavaScript становится особенно очевидной, когда она применяется для работы с ассоциативными массивами. Ниже показано, как можно использовать ее для вычисления суммарного объема инвестиций в
portfolio
:

function getvalue(portfolio) {

var total = 0.0;

for(stock in portfolio) { // Для каждой компании в portfolio:

var shares = portfolio[stock]; // получить количество акций

var price = getquote(stock); // отыскать стоимость одной акции

total += shares * price; // прибавить к суммарному значению

}

return total; // Вернуть сумму.

}

6.2.2. Наследование

Объекты в языке JavaScript обладают множеством «собственных свойств» и могут также наследовать множество свойств от объекта-прототипа. Чтобы разобраться в этом, необходимо внимательно изучить механизм доступа к свойствам. В примерах этого раздела для создания объектов с определенными прототипами используется функция inherit из примера 6.1.

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

var о = {} //о наследует методы объекта Object.prototype

o.х = 1; //и обладает собственным свойством х.

var р = inherit(о); // р наследует свойства объектов о и Object.prototype

p.у = 2; //и обладает собственным свойством у.

var q = inherit(p); // q наследует свойства объектов р, о и Object.prototype

q.z = 3; //и обладает собственным свойством z.

var s = q.toString; // toString наследуется от Object.prototype

q.x+q.y // => 3: x и у наследуются от о и p

Теперь предположим, что программа присваивает некоторое значение свойству х объекта о. Если объект о уже имеет собственное свойство (не унаследованное) с именем х, то операция присваивания просто изменит значение существующего свойства. В противном случае в объекте о будет создано новое свойство с именем х. Если прежде объект о наследовал свойство х, унаследованное свойство теперь окажется скрыто вновь созданным собственным свойством с тем же именем.

Поделиться с друзьями: