Глава 3.7. Использование объектов3.7.1. Объекты, свойства и методы3.7.1.1. Основные понятияКак уже отмечалось выше, JavaScript это язык программирования, основанный на объектах. Все объекты, доступные сценарию на языке JavaScript, подразделяются на три группы:
Объект JavaScript это неупорядоченный набор свойств. Свойство, являющееся функцией, называется методом. Для доступа к свойству объекта используется синтаксис: имя_объекта.имя_свойства Если название свойства задано текстовой строкой, то доступ к свойству возможен и так: имя_объекта["имя_свойства"] Этот синтаксис используется оператором итерации for in. Каждое свойство состоит из названия, значения и набора следующих атрибутов:
Новое свойство объекта создается просто присваиванием ему значения. Пусть, например, мы уже создали объект 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 используется нотация 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; } В дальнейшем мы можем вызвать этот метод так: При желании конструктор можно записать и короче, используя вложенное определение функции: 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) объектов.
JavaScript, в отличие от этих языков, основан на прототипах и не проводит различия между двумя приведенными понятиями: в нем есть только объекты. Некоторым аналогом класса здесь выступает прототип объекта, который определяет начальный набор свойств нового объекта. В процессе выполнения программы объект может получать новые свойства; более того, он может сам выступать в качестве прототипа при создании новых объектов. 3.7.2.2. Создание объектовВ языках, основанных на классах, класс объектов описывается отдельной декларацией класса. В
этой декларации мы можем указать специальные методы, называемые конструкторами, которые
создают экземпляры данного класса. Конструктор выделяет память для экземпляра, инициализирует
значения его свойств и выполняет другие необходимые действия. После написания декларации класса
мы можем создавать его экземпляры путем вызова операции Создание объектов в JavaScript происходит примерно так же, но здесь декларация конструктора
совпадает с декларацией класса. Иными словами, мы определяем конструктор как функцию, которая
создает объекты с заданным начальным набором свойств и их значений. Затем мы так же создаем
объекты вызовом операции 3.7.2.3. НаследованиеВ языках, основанных на классах, классы объектов образуют иерархию классов, в которой каждый класс может быть потомком какого-либо ранее определенного класса. Потомок класса наследует все его свойства, но может иметь дополнительные собственные свойства или изменять свойства своего предка. При этом набор свойств данного класса зафиксирован в его декларации и не может быть изменен в ходе выполнения программы. Можно сказать, что здесь текущее состояние реализуется экземплярами классов, методы реализуются классами, а наследование структурой и поведением. JavaScript поддерживает наследование, основанное на прототипах. С каждым конструктором связан соответствующий прототип объекта, и каждый объект, созданный конструктором, содержит неявную ссылку на этот прототип. Прототип, в свою очередь, может содержать ссылку на свой прототип и так далее. Так образуется цепочка прототипов. Ссылка на свойство объекта это ссылка на первый прототип в цепочке прототипов объекта, который содержит свойство с данным именем. Иными словами, если данный объект имеет свойство с данным именем, то используется ссылка на это свойство; если нет, то исследуется прототип этого объекта и т. д. В JavaScript текущее состояние и методы реализуются объектами, а структура и поведение наследуются. Все объекты, которое явно содержат свойство, которое содержит их прототип, разделяют это свойство и его значение. В отличие от языков, основанных на классах, свойства могут динамически добавляться к объектам и динамически удаляться. В частности, конструкторы не обязаны присваивать значения всем или некоторым свойствам создаваемого объекта. 3.7.2.4. РезюмеПеречисленные в этом разделе отличия объектной модели JavaScript от языков, основанных на классах, сведены в следующей таблице.
| ||||||||||||||||||||||