04. Объекты
Объектно ориентированное программирование
![]() |
Сравним работу с объектами в языках C++ и JavaScript. Объектно ориентированный язык C++ взят только потому, что мне он больше знаком. |
В языке C++ есть ключевое слово class. Например, можно создать класс Rectangle:
// Описание класса Rectangle (прямоугольник)
// Инициализирует в экземпляре класса переменные width и height
// Создаёт функцию square() -- вычисление площади
class Rectangle
{
public:
int width; // Это переменная-член класса
int height; // Это переменная-член класса
int square() {return width*height}; // Это функция-член класса
}
Описание класса не представляет собой какой-либо конкретный объект, а является шаблоном («документацией») для создания объектов данного типа. Слово Rectangle теперь становится обозначением нового типа данных (наряду с int). Можно написать:
int z;
Rectangle rect; // Создан объект rect. В этот объект скопированы
// переменные width и height, а также функция square
rect.width = 2; // Инициализирована переменная width в объекте rect
rect.height = 3; // Инициализирована переменная height в объекте rect
z = rect.square(); // Равно 6
В 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;
Rectangle rect(2,3); // Создан объект rect. Переменные объекта
// инициализированы при помощи функции-конструктора
z = rect.square(); // Равно 6
Что характерно, функции, описанные внутри класса доступны только для объектов этого класса.
Как мы видели, функции JavaScript более независимы: они не принадлежат никакому объекту (независимо от того, где описаны). Они связываются с объектом только в момент выполнения при помощи ключевого слова this. Ключевое слово this обозначает объект, в контексте которого вызывается функция. Если вызов функции явно не связан с объектом, то таким объектом выступает глобальный объект window.
В C++ ключевое слово this имеет другой смысл. Считается, что в функциях-членах класса всегда присутствует неявный аргумент this, который ссылается на объект (экземпляр класса), в котором эта функции вызывается.
В JavaScript this ни на что не ссылается во время описания! Ключевое слово this в JavaScript приобретает конкретный смысл только во время вызова функции, и связывается с тем объектом, в контексте которого функция работает.
Ещё раз посмотрите, заданы два объекта разных типов:
var rect = { x:10, y:20, square:sq };
var cube = { x:2, y:3, z:16, square:sq };
И одна функция:
function sq() {return this.x*this.y;}
Ключевое слово this в этой функции ни на что не ссылается, пока функция не будет вызвана.
rect.sq() // Сейчас this ссылается на объект rect
cube.sq() // Сейчас this ссылается на объект cube
sq() // Сейчас this ссылается на объект window
Итак, в C++ (и других подобных языках) есть классы — шаблоны, содержащие «документацию» на объекты. Для описания классов предусмотрено специальное ключевое слово class. Имя созданного класса используется наравне с ключевым словом, описывающим тип данных (таким как int) для создания объектов — экземпляров класса.
В JavaScript нет «настоящих» классов, но можно строить функции-конструкторы с описаниями шаблонов объектов. Создаются объекты при помощи функции-конструктора и оператора new.
Хотя в JavaScript нет настоящих классов, для удобства изложения будем называть классом функцию, используемую как конструктор, а объекты, созданные с её помощью — экземплярами класса или просто объектами.