ООП в JavaScript
Теоретичний опис принципів ООП в JavaScript може заняти дуже багато часу, і викликати багато суперечок навколо питання чи взагалі існують класи в JavaScript. Я не буду на цьому зупинятися, а відразу дам відповідь: Класів в JavaScript НЕМАЄ
Зміст
Загальний Опис
JavaScript -- це мова програмування, яка базується на об`єктах. Всі об'єкти поділяються на 3 групи:
- вбудовані об'єкти виконуючої системи
- об'єкти середовища, в якому виконується сценарій
- користувацькі об'єкти
об'єкт JavaScript -- це неупорядкований набір властивостей.
Метод -- це властивість, що є функцією. Приклад синтаксису доступу до властивості об'єкту:
імя_об'єкта.імя_властивості
або
імя_об'єкта["імя_властивості"]
Останній синтаксис використовується оператором for ... in. Кожне властивість складається з назви, значення і набору наступних атрибутів:
Атрибут |
Опис Атрибуту |
DontEnum |
Чи повинна властивість попадати в перелічення при обході оператором for..in |
DontDelete |
Заборона видалення даної властивості. Спроба програмно видалити дану властивість буде проигноровано. |
ReadOnly |
Заборона зміни цієї властивості. Спроба програмно змінити дану властивість буде проигноровано. |
Нова властивість об'єкту створюється просто присвоюванням йому значення. Нехай, наприклад, ми вже створили об'єкт MyObj. Задамо йому ім'я, та, наприклад, якесь значення:
MyObj.name = "Мій Об'єкт";
MyObj.value = 256;
Тепер наш об'єкт має 2 властивості: name та value. У таких властивостей, створених користувачем, всі перераховані вище атрибути скинуті в false. Надалі ми можемо змінювати значення цих властивостей або переглядати.
Створення об'єкта
Існує два способи створення нових об'єктів у JavaScript, а саме:
- Використання ініціалізатора об'єкта.
- Використання конструктора об'єктів.
Створення об'єктів за допомогою ініціалізатора
Цей спосіб дозволяє одночасно створити об'єкт і привласнити значення всіх або частини його властивостей. Він застосовується в тих випадках, коли ми створюємо об'єкт з унікальним набором властивостей. Ініціалізатор об'єкта має вигляд:
(Властивість: значення [, властивість: значення])
Властивість - ідентифікатор, що задає ім'я властивості; значення - вираз, що задає значення цієї властивості.
Наприклад, об'єкт MyObj з попереднього прикладу може бути створений так:
var MyObj = {name: "Dead", value: "256"};
Можливо конструювати об'єкт в об'єкті. Додамо ще одну властивість об'єкта MyObj, яка називається options і сама є об'єктом:
var MyObj = {name: "Dead", value: "256", options: {enabled: true, vud: false}};
Створення об'єктів за допомогою конструктора
Цей спосіб застосовується в тих випадках, коли ми хочемо створити "клас"(реально функцію конструктор) об'єктів з певним набором властивостей, а потім створювати нові об'єкти, просто вказуючи, до якого класу вони повинні належати. Для цього потрібно спочатку створити конструктор об'єктів, який є функцією спеціального виду, а саме:
- Ім'я функції задає ім'я створюваного "класу" об'єктів;
- Тіло функції повинно містити присвоювання початкових значень властивостям і методам створюваного об'єкту.
Наприклад, конструктор для об'єкта MyObj з попереднього прикладу може мати наступний вигляд:
function MyObj(name, value) { this.name = name; this.value = value; }
Зверніть увагу на використання операції this для доступу до властивостей об'єкта. Його особливості будуть розглянуті далі.
Тепер для створення нових об'єктів MyObj достатньо викликати цей конструктор в операції new, наприклад:
var myObjL = new MyObj("Indigo", 132);
Продемонструємо на прикладі об'єкт, який буде складатися з іншого об'єкту та ініціалізовуватиметься за допомогою конструктору:
function myOpt(enbl, vud) { this.enabled = enbl; this.vud = vud; }
function MyObj(name, value, options) { this.name = name; this.value = value; this.options = options; }
var myOpt = new myOpt(true, false); var myObjL = new MyObj("Indigo", 132, myOpt);
Для доступу до властивостей властивості options використовується нотація myObjL.options.enabled.
Ключове слово this
Ключове слово this в JavaScript працює своєрідно, не так, як в інших мовах, він не прив'язується статично ні до якого об'єкту, а залежить від контексту виклику.
Існує 4 випадки значення операції:
- Режим конструктора, якщо функція визивається через new як конструктор об'єкту, то this ставиться на стрворюваний об'єкт;
- Метод об'єкту, якщо функція запущена як властивість об'єкту, то в this буде посилання на цей об'єкт;
- Apply/Call, якщо функція визивається через методи Apply та Call, при такому визові функції this буде встановлено в об'єкт, що визивається;
- Простий виклик, при цьому виклику this стає ріним глобальному об'єкту (в браузері це window).
Створення методів
Оскільки методи є різновидом властивостей, вони створюються так само, як описано вище. Наприклад, ми можемо додати до конструктора об'єктів MyObj метод aboutObj, який буде виводити на екран браузера інформацію про властивості цього об'єкта:
function showObj() { document.write("Об'єкт: " + this.name + " " + this.version); }
function MyObj(name, version) { this.name = name; this.version = version; this.aboutObj = showObj; }
В подальшому ми можемо викликати цей метод:
myObjL.showObj();
При бажанні можна записати короче:
function MyObj(name, version) { this.name = name; this.version = version; this.aboutObj = function() { document.write("Об'єкт: " + this.name + " " + this.version); } }
Прототипи об'єктів
Більшість об'єктно-орієнтованих мов (наприклад, Java і C + +) засновані на двох базових поняттях: класи об'єктів і екземпляри (instances) об'єктів.
- Клас об'єктів - це абстрактне поняття, що описує всі властивості даного класу (в Java ці властивості називаються полями й методами, а в C + + членами класу, але суть від цього не змінюється).
- Екземпляр об'єкту - це реалізація класу, тобто конкретний об'єкт, наділений всіма властивостями даного класу.
JavaScript, на відміну від цих мов, заснований на прототипах і не проводить відмінності між двома наведеними поняттями: у ньому є тільки об'єкти. Деяким аналогом класу тут виступає прототип об'єкта, який визначає початковий набір властивостей нового об'єкта. У процесі виконання програми об'єкт може отримувати нові властивості; більше того, він може сам виступати як прототип при створенні нових об'єктів.
Припустимо, що ми хочемо в процесі виконання сценарію додати нову властивість security (безпека) класу об'єктів Options (підкреслимо ще раз - класу об'єктів, а не окремому його представнику myOptions). Для цього використовується властивість prototype об'єкта Function:
Options.prototype.security = null;
Тепер ми можемо присвоїти значення новому властивості об'єкта:
myObjL.options.security = "Велика";
Для видалення властивостей об'єктів використовується операція delete, наприклад:
delete Options.prototype.security;
Видалення об'єктів
Можна видалити раніше створений об'єк:
delete myObjL;