09. Функции. Часть 3. Конструкторы

Классы JavaScript

Эта страничка завершает обзор базового JavaScript. В следующей заметке мы переходим к клиентской части, то есть к вопросам программирования гипертекстовых страниц средствами JavaScript.

Соглашение об именовании классов и объектов

Имена классов принято начинать с первой заглавной буквы: Date, Array, String, Point. Имена объектов принято записывать строчными буквами: date, arr, str, point1.

Еще раз о классах JavaScript

Класс в JavaScript описывается при помощи функции-конструктора.

Заметим еще раз, что JavaScript (до версии 2.0) не поддерживает «настоящих» классов, в языке нет специальной конструкции class, при помощи которой можно было бы строить классы. Классы в JavaScript моделируются при помощи функции-конструктора, и прототипа — специального объекта, который является предопределённым свойством любой функции, в том числе и той, которую мы рассматриваем как конструктор. Поэтому точнее было бы называть шаблоны объектов JavaScript «псевдоклассами». Мы используем термин «класс» в его ассоциативной связи с «настоящими» классами объектно-ориентированных языков программирования.

Функция-конструктор не является какой-то особой конструкцией в JavaScript (подобно конструкции class). Мы «приспосабливаем» функцию для описания класса (в качестве шаблона для построения однотипных объектов) опираясь на то, что ключевое слово this внутри функции связано с тем объектом, в контексте которого функция вызывается.

Объекты, на основе функций-шаблонов («классов») создаются при помощи оператора new:


var ob = new Point(x,y);

Работает это так.

Оператор new создает пустой объект. Ключевое слово this внутри Point будет относиться к этому объекту. Поэтому инструкция типа this.x = x внутри Point создаст в этом объекте свойство x и присвоит этому свойству значение соответствующего аргумента.

В объекте создаются и инициализируются свойства при помощи функции Point. Объекты, построенные по одному шаблону, конечно, могут иметь разные значения своих свойств. Более того, во время работы с объектами, их свойства могут меняться.

В объекте можно создавать и инициализировать методы, ведь метод — это условное название для свойства в том случае, когда значением свойства является функция.

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

После создания пустого объекта оператор new устанавливает в этом объекте ссылку на прототип конструктора. Теперь все, что описано в прототипе конструктора становится доступным каждому созданному с его помощью объекту.

Прототип конструктора — идеальное место для хранения методов объектов и свойств-констант.

Итак, классы JavaScript описываются при помощи функций. Такие функции называются функциями-конструкторами. Свойства объектов создаются и инициализируются внутри этих функций, а методы и константы описываются в прототипе этих функций.

Ниже ещё раз показан пример описания класса Rectangle и создание при помощи этого класса объекта rect.


// Конструктор класса Rectangle
function Rectangle(width, height)
{
  // Свойства класса
  this.width  = width;
  this.height = height;
}
// Методы и константы класса
Rectangle.prototype.square=function(){return this.width*this.height;};
Rectangle.prototype.IN2 = 2.54*2.54; // Добавляем константу в прототип 

// Создать прямоугольник (размеры в сантиметрах)
var rect = new Rectangle(12,85);  
// Вычислить его площадь в квадратных дюймах
alert(rect.IN2*rect.square()); // 6580.632 

Свойства и методы классов

Функции, в том числе и функции-конструкторы — это объекты. Значит, они могут иметь собственные свойства и методы, которые будут относиться ко всему классу (а не к конкретным объектам класса).

Для описанного выше класса Rectangle можно, например, задать свойство UNIT, которое будет хранить единичный прямоугольник:


Rectangle.UNIT = new Rectangle(1,1);

Можно определить метод, который принимает два прямоугольника и возвращает ссылку на прямоугольник с большей площадью:


Rectangle.maxSquare = function (x,y)
{
  return x.square() > y.square() ? x : y; 
};

Объект Rectangle.UNIT и функция Rectangle.maxSquare являются свойством и методом конструктора Rectangle. Они не относятся ни к какому объекту, построенному при помощи Rectangle, и не принадлежат прототипу этого конструктора.

Вспомним константы, которые приводились в заметке 1:


Number.MAX_VALUE  // Максимально возможное число
Number.MIN_VALUE  // Наименьшее (ближайшее к нулю) число
Number.NaN        // Аналог глобального NaN
Number.POSITIVE_INFINITY // Аналог глобального Infinity
Number.NEGATIVE_INFINITY // Аналог глобального -Infinity

Эти константы являются свойствами конструктора Number.

А вот другой пример: метод String.FromCharCode. Эта функция является методом самого конструктора String. Она возвращает строку, содержащую символы, коды Unicode которых указаны в качестве аргументов:


var str = String.fromCharCode(0x043B, 0x0438, 0x0441, 0x0430);
alert (str); // "лиса"

На этом мы заканчиваем краткий обзор базовой части языка JavaScript и переходим к клиентской части, то есть к вопросам программирования гипертекстовых страниц средствами JavaScript.