# Статические и фабричные методы Методы и свойства, которые не привязаны к конкретному экземпляру объекта, называют "статическими". Их записывают прямо в саму функцию-конструктор. [cut] ## Статические свойства В коде ниже используются статические свойства `Article.count` и `Article.DEFAULT_FORMAT`: ```js function Article() { Article.count++; } Article.count = 0; // статическое свойство-переменная Article.DEFAULT_FORMAT = "html"; // статическое свойство-константа ``` Они хранят данные, специфичные не для одного объекта, а для всех статей целиком. Как правило, это чаще константы, такие как формат "по умолчанию" `Article.DEFAULT_FORMAT`. ## Статические методы С примерами статических методов мы уже знакомы: это встроенные методы [String.fromCharCode](http://javascript.ru/String.fromCharCode), [Date.parse](http://javascript.ru/Date.parse). Создадим для `Article` статический метод `Article.showCount()`: ```js //+ run function Article() { Article.count++; //... } Article.count = 0; Article.showCount = function() { *!* alert( this.count ); // (1) */!* } // использование new Article(); new Article(); Article.showCount(); // (2) ``` Здесь `Article.count` -- статическое свойство, а `Article.showCount` -- статический метод. Обратим внимание на использование `this` в примере выше. Несмотря на то, что переменная и метод -- статические, он всё ещё полезен. В строке `(1)` он равен `Article`. ## Пример: сравнение объектов Ещё один хороший способ применения -- сравнение объектов. Например, у нас есть объект `Journal` для журналов. Журналы можно сравнивать -- по толщине, по весу, по другим параметрам. Объявим "стандартную" функцию сравнения, которая будет сравнивать по дате издания. Эта функция сравнения, естественно, не привязана к конкретному журналу, но относится к журналам вообще. Поэтому зададим её как статический метод `Journal.compare`: ```js function Journal(date) { this.date = date; // ... } // возвращает значение, большее 0, если A больше B, иначе меньшее 0 Journal.compare = function(journalA, journalB) { return journalA.date - journalB.date; }; ``` В примере ниже эта функция используется для поиска самого раннего журнала из массива: ```js //+ run function Journal(date) { this.date = date; this.formatDate = function(date) { return date.getDate() + '.' + (date.getMonth() + 1) + '.' + date.getFullYear(); }; this.getTitle = function() { return "Выпуск от " + this.formatDate(this.date); }; } *!* Journal.compare = function(journalA, journalB) { return journalA.date - journalB.date; }; */!* // использование: var journals = [ new Journal(new Date(2012, 1, 1)), new Journal(new Date(2012, 0, 1)), new Journal(new Date(2011, 11, 1)) ]; function findMin(journals) { var min = 0; for (var i = 0; i < journals.length; i++) { *!* // используем статический метод if (Journal.compare(journals[min], journals[i]) > 0) min = i; */!* } return journals[min]; } alert( findMin(journals).getTitle() ); ``` **Статический метод также можно использовать для функций, которые вообще не требуют наличия объекта.** Например, метод `formatDate(date)` можно сделать статическим. Он будет форматировать дату "как это принято в журналах", при этом его можно использовать в любом месте кода, не обязательно создавать журнал. Например: ```js //+ run function Journal() { /*...*/ } Journal.formatDate = function(date) { return date.getDate() + '.' + (date.getMonth()+1) + '.' + date.getFullYear(); } // ни одного объекта Journal нет, просто форматируем дату alert( *!*Journal.formatDate(new Date)*/!* ); ``` ## Фабричные методы Рассмотрим ситуацию, когда объект нужно создавать различными способами. Например, это реализовано во встроенном объекте [Date](/datetime). Он по-разному обрабатывает аргументы разных типов: