09. Функции. Часть 3. Конструкторы
Классы и объекты
![]() |
В объектно-ориентированных языках программирования объекты рассматриваются как экземпляры класса. Классы в JavaScript можно описывать при помощи функции-конструктора, а объекты — экземпляры класса — строить с помощью оператора new и вызова конструктора: var объект = new Конструктор(); |
Что такое объект
Мы определяли объект, как множество неупорядочных пар «свойство:значение». Объекты легко создавать при помощи литералов:
var ob = {x:1,y:2};
Что такое класс
В объектно-ориентированных языках программирования объекты рассматриваются как экземпляры класса. Класс — это «документация» на однотипные объекты, своего рода шаблон, — в нём описываются свойства и методы, которые должны принадлежать каждому экземпляру класса.
Таким образом, класс позволяет создавать не один уникальный объект (подобный объекту ob, приведённому выше), а целое множество однотипных объектов.
Во многих объектно-ориентированных языках программирования для описания класса имеется специальная синтаксическая конструкция, например, в Си++ — это конструкция class.
Вот как в Си++ можно определить класс для работы с прямоугольниками:
// Описание класса Rectangle (прямоугольник)
// Инициализирует в экземпляре класса переменные width и height
// Создаёт функцию square() -- вычисление площади
class Rectangle
{
public:
int width; // Это переменная-член класса
int height; // Это переменная-член класса
int square() {return width*height}; // Это функция-член класса
}
Описание класса не представляет собой какой-либо конкретный объект, а является шаблоном для создания объектов данного типа.
Слово Rectangle становится обозначением нового типа данных (наряду с int, char и другими встроенными типами).
Можно написать:
int z; // Описана переменная z целочисленного типа
Rectangle rect; // Создан объект rect
rect.width = 2; // Инициализирована переменная width в объекте rect
rect.height = 3; // Инициализирована переменная height в объекте rect
z = rect.square(); // Равно 6 -- результат работы метода square
В C++ можно описать функцию-конструктор. Делается это так:
// Описание класса Rectangle (прямоугольник)
// Инициализирует в экземпляре класса переменные width и height
// Создаёт функцию square() -- вычисление площади
// Описывает функцию-конструктор
class Rectangle
{
public:
int width; // Это переменная-член класса
int height; // Это переменная-член класса
Rectangle(int x, int y) // Функция-конструктор класса.
{ // Ее имя совпадает с именем класса
width = x;
height = y;
}
int square() {return width*height}; // Это функция-член класса
}
Теперь можно написать:
int z; // Описана переменная z целочисленного типа
Rectangle rect(2,3); // Создан объект rect. Переменные объекта
// инициализированы при помощи функции-конструктора
z = rect.square(); // Равно 6 -- результат работы метода square
В JavaScript нет специальной синтаксической конструкции для создания класса (хотя такая конструкция планируется в версии 2.0).
Но классы (как мы уже видели) в JavaScript можно задавать описанием функции-конструктора, а объекты — экземпляры класса — строить с помощью оператора new и вызова конструктора.
Замечание 1. Классы JavaScript имеют особенности, поэтому их часто называют не классами, а псевдоклассами (по отношению к классам таких языков программирования, как Си++, Java или C#). Мы всё же будем использовать термин «класс», ибо он короче, и правильно отражает суть: создание однотипных объектов на базе построенной «документации».
Замечание 2. Заметим, что описание любой функции — это «документация» на создание объекта вызова, внутри которого будет работать описанный код. В частности, формальные аргументы в объекте вызова превращаются в одноименные свойства, и в них заносятся значение фактических аргументов.
Посмотрим, как в JavaScript можно описать класс Rectangle, а затем создавать объекты, экземпляры этого класса.
Сначала опишем соответствующую функцию конструктор:
// Конструктор класса Rectangle
function Rectangle(width, height)
{
// Свойства класса
this.width = width;
this.height = height;
// Методы класса
this.square = function () { return this.width * this.height;};
}
А теперь будем создавать объекты — экземпляры этого класса, и работать с ними.
var rect1 = new Rectangle(1,2); // Создали первый экземпляр
var rect2 = new Rectangle(10,20); // Создали второй экземпляр
alert(rect1.square()); // 2 -- нашли площадь первого прямоугольника
alert(rect2.square()); // 200 -- нашли площадь второго прямоугольника
Запуск примера: praxis/09/examples/01/test.htm
Замечание. Вспомним, как работает пара «new конструктор». Оператор new создает пустой объект и передает его в качестве неявного аргумента this конструктору. Конструктор создает в объекте свойства (и методы, которые ведь тоже есть свойства). В частности, инструкция
var rect1 = new Rectangle(1,2);
делает следующее.
- Создаётся (где-то в памяти) пустой объект (экземпляр класса Object).
-
Конструктор Rectangle запускается в контексте
созданного (пустого объекта). При этом:
- 2.1. В объекте создается свойство width и ему присваивается значение 1 (результат выполнения инструкции this.width = width;)
- 2.2. В объекте создается свойство height и ему присваивается значение 2 (результат выполнения инструкции this.height = height;)
- 2.3. В объекте создается свойство square и ему присваивается значение функционального литерала function(){return this.width*this.height;}. (Нудно отметим, что экземпляр литерала создается где-то в памяти, а в свойство square записывается ссылка на него.)
- Переменная rect1 присваивается ссылка на созданный объект.