Документация JavaScript
| Документация DHTML | Документация Smarty | SVG/VML Графика и JavaScript
| Документация bash |
Глава 3.7. Использование объектов
3.7.1. Объекты, свойства и методы
3.7.1.1. Основные понятия
Как уже отмечалось выше, JavaScript это язык программирования, основанный на объектах. Все объекты, доступные сценарию на языке JavaScript, подразделяются на три группы:
- встроенные объекты исполняющей системы;
- объекты среды, в которой исполняется сценарий (т. е. либо объекты клиента, либо объекты сервера);
- пользовательские объекты, создаваемые сценарием в процессе его выполнения.
Объект JavaScript это неупорядоченный набор свойств. Свойство, являющееся функцией, называется методом. Для доступа к свойству объекта используется синтаксис:
имя_объекта.имя_свойства
Если название свойства задано текстовой строкой, то доступ к свойству возможен и так:
имя_объекта["имя_свойства"]
Этот синтаксис используется оператором итерации for in.
Каждое свойство состоит из названия, значения и набора следующих атрибутов:
Атрибут | Описание |
---|---|
DontEnum | Свойство не должно попадать в перечисление при итерации объекта оператором for in. |
DontDelete | Попытка программно удалить данное свойство будет проигнорирована. См. описание операции delete. |
ReadOnly | Неизменяемое свойство. Попытка программно изменить данное свойство будет проигнорирована. (Отметим, что в некоторых случаях значение свойства с этим атрибутом может быть изменено через внешнюю среду.) |
Новое свойство объекта создается просто присваиванием ему значения. Пусть, например, мы уже создали объект myBrowser, который должен описывать наш Веб-обозреватель. Это описание будет состоять из названия обозревателя (name) и его версии (version). Для создания указанных свойств мы должны включить в сценарий следующие строки:
myBrowser.name = "Microsoft Internet Explorer"; myBrowser.version = "5.5";
У таких свойств, созданным пользователем, все перечисленные выше атрибуты сброшены в false. В дальнейшем мы можем изменять значения этих свойств или извлекать их, например:
document.write(myBrowser.name, myBrowser.version);
Существует два способа создания новых объектов в JavaScript, а именно:
- Использование инициализатора объекта.
- Использование конструктора объектов.
3.7.1.2. Создание объектов с помощью инициализатора
Этот способ позволяет одновременно создать объект и присвоить значения всем или части его свойств. Он применяется в тех случаях, когда мы создаем объект с уникальным набором свойств. Инициализатор объекта имеет вид:
{свойство:значение [,свойство:значение]?}
Здесь свойство идентификатор, задающий имя свойства, а значение выражение, задающее значение этого свойства.
Например, объект myBrowser из предыдущего примера может быть создан так:
var myBrowser = {name: "Microsoft Internet Explorer", version: "5.5"};
Усложним этот пример, добавив еще одно свойство объекта myBrowser, которое называется options (опции обозревателя) и само является объектом:
var myBrowser = {name: "Microsoft Internet Explorer", version: "5.5", options: {enableJava: true, enableCookies: false}};
3.7.1.3. Создание объектов с помощью конструктора
Этот способ применяется в тех случаях, когда мы хотим создать класс объектов с определенным набором свойств, а затем создавать новые объекты, просто указывая, к какому классу они должны принадлежать. Для этого нужно сначала создать конструктор объектов, который является функцией специального вида, а именно:
- имя функции задает имя создаваемого класса объектов;
- тело функции должно содержать присваивание начальных значений свойствам и методам создаваемого объекта.
Например, конструктор для класса объектов Browser из предыдущего примера может иметь следующий вид:
function Browser(name, version) { this.name = name; this.version = version; }
Обратите внимание на использование операции this для доступа к свойствам объекта.
Теперь для создания новых объектов класса Browser достаточно вызвать этот конструктор в операции new, например:
var myBrowser = new Browser("Microsoft Internet Explorer", "5.5");
Вспомним теперь, что выше мы добавили свойство options объекта Browser, которое само является объектом. Перепишем приведенный пример с учетом этого свойства:
function Options(enableJava, enableCookies) { this.enableJava = enableJava; this.enableCookies = enableCookies; } function Browser(name, version) { this.name = name; this.version = version; this.options = options; } var myOptions = new Options(true, false); var myBrowser = new Browser("Microsoft Internet Explorer", "5.5", myOptions);
Для доступа к свойствам свойства options используется нотация myBrowser.options.enableJava
.
3.7.1.4. Создание методов
Поскольку методы являются разновидностью свойств, они создаются так же, как описано выше. Например, мы можем добавить к конструктору объектов Browser метод aboutBrowser, который будет выводить на экран обозревателя информацию о свойствах этого объекта:
function showBrowser() { document.write("Обозреватель: " + this.name + " " + this.version); } function Browser(name, version) { this.name = name; this.version = version; this.aboutBrowser = showBrowser; }
В дальнейшем мы можем вызвать этот метод так: myBrowser.aboutBrowser()
.
При желании конструктор можно записать и короче, используя вложенное определение функции:
function Browser(name, version) { this.name = name; this.version = version; this.aboutBrowser = function() { document.write("Обозреватель: " + this.name + " " + this.version); } }
3.7.1.5. Изменение прототипа объекта
Допустим, что мы хотим в процессе выполнения сценария добавить новое свойство security (безопасность) классу объектов Options (подчеркнем еще раз классу объектов, а не отдельному его представителю myOptions). Для этого используется свойство prototype объекта Function:
Options.prototype.security = null;
Теперь мы можем присвоить значение новому свойству объекта:
myBrowser.options.security = "Высокая";
Для удаления свойств объектов используется операция delete, например:
delete Options.prototype.security;
JavaScript позволяет нам задать новый прототип для класса пользовательских объектов (прототипы встроенных объектов доступны только для чтения). Рассмотрим такой пример:
function Circle(radius) { this.radius = radius; } Circle.prototype.area = function() { return Math.PI * this.radius * this.radius; } function FullCircle(x, y, radius) { this.x = x; this.y = y; this.radius = radius; } FullCircle.prototype = Circle.prototype; var myCircle = new FullCircle(0, 0, 1); document.write(myCircle.area());
В этом примере сначала определяется класс объектов Circle со свойством radius и методом area, возвращающим площадь круга. Затем определяется класс FullCircle, конструктор которого дополнительно содержит координаты центра окружности. Затем указывается, что он наследует прототип класс Circle. После этого мы создаем объект myCircle и вызываем его метод area, который он унаследовал от прототипа класса Circle.
3.7.1.6. Удаление объектов
Мы можем удалить ранее созданный объект с помощью операции delete, например:
delete myBrowser;
3.7.2. Объектная модель JavaScript
Чтение этого раздела не обязательно для того, чтобы научиться писать сценарии на языке JavaScript. Его назначение состоит в том, чтобы дать представление о внутренних механизмах реализации JavaScript тем программистам, которые имеют опыт работы с другими объектно-ориентированными языками программирования. Если эти детали Вас не интересуют, то можете перейти к следующему разделу.
3.7.2.1. Прототипы объектов
Большинство объектно-ориентированных языков (например, Java и C++) основаны на двух базовых понятиях: классы объектов и экземпляры (instances) объектов.
- Класс объектов это абстрактное понятие, описывающее все свойства данного класса (в Java эти свойства называются полями и методами, а в C++ членами класса, но суть от этого не меняется).
- Экземпляр объекта это реализация класса, т. е. конкретный объект, наделенный всеми свойствами данного класса.
JavaScript, в отличие от этих языков, основан на прототипах и не проводит различия между двумя приведенными понятиями: в нем есть только объекты. Некоторым аналогом класса здесь выступает прототип объекта, который определяет начальный набор свойств нового объекта. В процессе выполнения программы объект может получать новые свойства; более того, он может сам выступать в качестве прототипа при создании новых объектов.
3.7.2.2. Создание объектов
В языках, основанных на классах, класс объектов описывается отдельной декларацией класса. В
этой декларации мы можем указать специальные методы, называемые конструкторами, которые
создают экземпляры данного класса. Конструктор выделяет память для экземпляра, инициализирует
значения его свойств и выполняет другие необходимые действия. После написания декларации класса
мы можем создавать его экземпляры путем вызова операции new имя_конструктора(...)
.
Создание объектов в JavaScript происходит примерно так же, но здесь декларация конструктора
совпадает с декларацией класса. Иными словами, мы определяем конструктор как функцию, которая
создает объекты с заданным начальным набором свойств и их значений. Затем мы так же создаем
объекты вызовом операции new имя_конструктора(...)
.
3.7.2.3. Наследование
В языках, основанных на классах, классы объектов образуют иерархию классов, в которой каждый класс может быть потомком какого-либо ранее определенного класса. Потомок класса наследует все его свойства, но может иметь дополнительные собственные свойства или изменять свойства своего предка. При этом набор свойств данного класса зафиксирован в его декларации и не может быть изменен в ходе выполнения программы. Можно сказать, что здесь текущее состояние реализуется экземплярами классов, методы реализуются классами, а наследование структурой и поведением.
JavaScript поддерживает наследование, основанное на прототипах. С каждым конструктором связан соответствующий прототип объекта, и каждый объект, созданный конструктором, содержит неявную ссылку на этот прототип. Прототип, в свою очередь, может содержать ссылку на свой прототип и так далее. Так образуется цепочка прототипов. Ссылка на свойство объекта это ссылка на первый прототип в цепочке прототипов объекта, который содержит свойство с данным именем. Иными словами, если данный объект имеет свойство с данным именем, то используется ссылка на это свойство; если нет, то исследуется прототип этого объекта и т. д.
В JavaScript текущее состояние и методы реализуются объектами, а структура и поведение наследуются. Все объекты, которое явно содержат свойство, которое содержит их прототип, разделяют это свойство и его значение. В отличие от языков, основанных на классах, свойства могут динамически добавляться к объектам и динамически удаляться. В частности, конструкторы не обязаны присваивать значения всем или некоторым свойствам создаваемого объекта.
3.7.2.4. Резюме
Перечисленные в этом разделе отличия объектной модели JavaScript от языков, основанных на классах, сведены в следующей таблице.
Модель, основанная на классах (Java и C++) |
Модель, основанная на прототипах (JavaScript) |
---|---|
Класс объектов и экземпляр объекта это различные понятия. | Все объекты являются экземплярами объектов. |
Класс определяется декларацией класса. Экземпляр класса создается конструктором. | Набор объектов определяется и создается функцией-конструктором. |
Новый объект создается операцией new. | Новый объект создается операцией new. |
Существует иерархия классов, в которой новые классы являются потомками ранее определенных. | Существует иерархия объектов, в которой объект имеет прототип, заданной функцией-конструктором. |
Свойства наследуются по цепочке классов-потомков. | Свойства наследуются по цепочке прототипов. |
Декларация класса определяет все свойства всех экземпляров данного класса. Набор свойств не может динамически изменяться в ходе выполнения программы. | Конструктор или прототип определяют начальный набор свойств. Свойства набора объектов или отдельного объекта могут динамически добавляться и удаляться в ходе выполнения программы. |