We're looking for a user researcher to understand the needs of developers and designers. Is this you or someone you know? Check out the post: https://mzl.la/2IGzdXS

Переклад не закінчено. Будь ласка, допоможіть перекласти цю статтю з англійської.

В цій статті ми розглянемо основи синтаксису JavaScript об'єктів і заново вивчимо деякий функціонал JavaScript, який ми досліджували  раніше на курсі, підтверджуючи той факт, що велика частина функціоналу, з яким ми вже зіткнулись, в дійсності є об'єктами.

Необхідні знання: Елементарна комп'ютерна грамотність, базове розуміння HTML та CSS, знайомство з основами JavaScript (див. First steps та Building blocks).
Мета: Розуміння основ теоріі об'єктно-орієнтованого програмування, як це пов'язано з JavaScript ("більшість речей є об'єктами'), і як почати роботу з об'єктами JavaScript.

Основи об'єктів

Об'єкт - це сукупність пов'язаних даних і/або функціональності (які зазвичай складаються з декількох змінних і функцій, які називаються властивостями та методами, якщо вони знаходяться всередині об'єктів). Давайте розберемо приклад , щоб показати, як вони виглядають.

Щоб почати, скопіюйте собі oojs.html файл. У ньому міститься дуже мало —  <script> елемент для написання нашого вихідного коду. Ми будемо використовувати це як основу для вивчення основ синтаксису об'єктів. Під час роботи з цим прикладом ви повинні відкрити developer tools JavaScript console, щоб вводити деякі команди.

Як і в багатьох випадках в JavaScript, створення об'єкту часто починається з визначення та ініціалізації змінної. Спробуйте ввести наступний нижче код в завантажений файл JavaScript, а потім збережіть і оновіть сторінку:

var person = {};

Якщо ви введете person в консоль JS і натиснете кнопку, то повинні отримати наступний результат:

[object Object]

Вітаємо, ви щойно створили свій перший об'єкт. Але це порожній об'єкт, тому ми не можемо з ним багато чого зробити. Давайте доповнимо наш об'єкт, щоб він виглядав так:

var person = {
  name: ['Bob', 'Smith'],
  age: 32,
  gender: 'male',
  interests: ['music', 'skiing'],
  bio: function() {
    alert(this.name[0] + ' ' + this.name[1] + ' is ' + this.age + ' years old. He likes ' + this.interests[0] + ' and ' + this.interests[1] + '.');
  },
  greeting: function() {
    alert('Hi! I\'m ' + this.name[0] + '.');
  }
};

Після збереження та оновлення спробуйте ввести деякі з наведених нижче елементів у консолі JS:

person.name[0]
person.age
person.interests[1]
person.bio()
person.greeting()

Тепер всередині об'єкта є деякі дані та функціонал, і тепер до них можна отримати доступ за допомогою легкого і простого синтаксису!

Заувага: Якщо у вас виникли проблеми із застосуванням файлу в роботі, спробуйте порівняти свій код з нашою версією  — див. oojs-finished.html (також see it running live). Одна з найпоширеніших помилок, коли ви починаєте роботу з об'єктами, ставити кому в кінці останнього члена - це призводить до помилки.

Отже, що тут відбувається? Об'єкт складається з декількох елементів, кожен з яких має назву (наприклад, name та age вище), і значення (наприклад, ['Bob', 'Smith'] та 32). Кожна пара назва/значення повинна бути відокремлена комою, а назва і значення в кожному випадку розділяються між собою двокрапкою. Синтаксис завжди дотримується цього шаблону:

var objectName = {
  member1Name: member1Value,
  member2Name: member2Value,
  member3Name: member3Value
}

Значенням члена об'єкта може бути майже все — в нашому об'єкті person є рядок, число, два масиви та дві функції.  Перші чотири елементи є елементами даних, що відносяться до властивостей об'єкта. Останні два елементи - це функції, які дозволяють об'єкту щось зробити з цими елементами даних, називаються методами об'єкта.

Такі об'єкти називаються літералами об'єкта (object literal) - ми буквально вписали весь вміст об'єкта для його створення. Цей спосіб сильно відрізняється від об'єктів, реалізованих класами, які ми розглянемо пізніше.

Дуже часто створення об'єкта за допомогою літералу використовується, коли вам потрібно перенести  певним чином ряд структурованих, пов'язаних елементів даних, наприклад, надсилаючи запит на сервер для розміщення їх в базі даних. Відправка одного об'єкта набагато ефективніша, ніж відправлення кількох елементів окремо, а також з ним легше працювати, ніж з масивом, коли ви хочете ідентифікувати окремі елементи за назвою.

Крапкова нотація (Dot notation)

Вище ми отримали доступ до властивостей об'єкта та методів використовуючи крапкову нотацію (dot notation). Ім'я об'єкта (person) діє як простір імен (namespace) - його потрібно вводити першим для того, щоб ми могли отримати доступ до всього, що вкладено (encapsulated) всередині об'єкта.  Далі ви ставите крапку, після якої вказуєте елемент, який хочете отримати - це може бути іназва простої властивості,  елемент масиву або виклик одного з методів об'єкту, наприклад:

person.age
person.interests[1]
person.bio()

Sub-простори імен (Sub-namespaces)

Значенням елемента об'єкта можна зробити навіть інший об'єкт. Наприклад, спробуйте змінити значення властивості name з такого

name: ['Bob', 'Smith'],

на

name : {
  first: 'Bob',
  last: 'Smith'
},

Тут ми ефективно створюємо sub-простір імен. Звучить складно, але насправді це не так - щоб отримати доступ до необхідних елементів, вам просто потрібно зробити ще один додатковий крок через крапку. Спробуйте це у консолі JS:

person.name.first
person.name.last

Важливо: на цьому етапі вам також доведеться переглянути код вашого методу і змінити екземпляри з 

name[0]
name[1]

на 

name.first
name.last

Інакше ваші методи більше не працюватимуть.

Дужкова нотація (Bracket notation)

Існує ще один спосіб отримати доступ до властивостей об'єкту - використання дужкової нотації (bracket notation). Замість написання цього коду:

person.age
person.name.first

Ви можете використовувати:

person['age']
person['name']['first']

Це виглядає дуже схожим на те, як ви отримуєте доступ до елементів у масиві, і в принципі так воно і є - замість використання числових індексів для вибору елемента, ви асоціюєте ім'я для кожного значення. Не дивно, що ці об'єкти іноді називають асоціативними масивами - вони зіставляють рядки зі значеннями так само, як масиви зіставляють числові індекси зі значеннями.

Встановлення елементів об'єкта

Досі ми розглядали лише повернення (або отримання) елементів об'єктів - ви також можете встановити (оновити) значення елемента об'єкта, просто оголосивши елемент, який ви хочете встановити (використовуючи крапкову або дужкову нотацію), наприклад:

person.age = 45;
person['name']['last'] = 'Cratchit';

Спробуйте ввести ці рядки, а потім знову поверніть елементи, щоб побачити, як вони змінилися:

person.age
person['name']['last']

Ви можете не просто оновлювати і встановлювати значення властивостей і методів об'єкта, а так сам створювати абсолютно нові елементи. Наприклад:

person['eyes'] = 'hazel';
person.farewell = function() { alert("Bye everybody!"); }

Тепер ви можете перевірити ваші нові елементи:

person['eyes']
person.farewell()

Одним із корисних аспектів дужкової нотації є те, що вона може використовуватись не тільки для динамічного встановлення значень елементів, але й для їх імен. Припустимо, ми хочемо, щоб користувачі могли зберігати користувацькі типи даних, ввівши ім'я та значення елемента в два текстові поля? Ми могли б отримати такі значення:

var myDataName = nameInput.value;
var myDataValue = nameValue.value;

Потім ми могли б додати новий елемент і його значення в об'єкт person таким чином:

person[myDataName] = myDataValue;

Щоб перевірити це, спробуйте додати наступні рядки до свого коду:

var myDataName = 'height';
var myDataValue = '1.75m';
person[myDataName] = myDataValue;

Тепер збережіть й оновіть, і введіть наступне:

person.height

Додавання властивості об'єкту з використанням наведеного вище методу неможливе з крапковою нотацією, яка може приймати лише літеральне ім'я елемента, а не значення змінної, що вказує на ім'я. 

Що таке "this"?

Ви могли помітити щось дивне в наших методах. Подивіться на це, наприклад:

greeting: function() {
  alert('Hi! I\'m ' + this.name.first + '.');
}

Ймовірно, вас цікавить, що таке "this"?  this - це ключове слово, яке посилається на поточний об'єкт, всередині якого написаний код - тому, в нашому випадку, this рівнозначний об'єкту person. Але чому б просто не написати person? Як ви побачите в статті  Об'єктно-орієнтований JavaScript для початківців, коли ми починаємо створювати конструктори, і т.д., this дуже корисний - він завжди буде гарантувати, що використовується правильне значення, коли контекст елемента змінюється (наприклад, два різні екземпляри об'єкта person можуть мати різні імена, але захочуть використовувати своє власне при вітанні). 

Давайте проілюструємо, що ми маємо на увазі з спрощеною парою об'єктів person:

var person1 = {
  name: 'Chris',
  greeting: function() {
    alert('Hi! I\'m ' + this.name + '.');
  }
}

var person2 = {
  name: 'Brian',
  greeting: function() {
    alert('Hi! I\'m ' + this.name + '.');
  }
}

В цьому випадку, person1.greeting() виведе "Hi! I'm Chris."; person2.greeting() з іншого боку виведе "Hi! I'm Brian.", хоча код методу однаковий в обох випадках. Як ми вже говорили раніше, this рівнозначний об'єкту, всередині якого знаходиться код - це не дуже корисно, коли ви пишете літерали об'єктів вручну, але це дійсно допомагає, коли ви генеруєте об'єкти динамічно (наприклад, використовуючи конструктори). Пізніше це стане зрозумілішим.

Ви використовували об'єкти постійно

Поки ви проходили ці приклади, ймовірно, ви помітили, що крапкова нотація, яку ви використовували, виглядає дуже знайомо. Це тому, що ви використовували її протягом усього курсу! Кожного разу, коли ми працювали над прикладом, який використовував вбудований API-інтерфейс браузера або JavaScript об'єкт, ми використовували об'єкти, тому що такі функції побудовані з використанням тих же структур об'єктів, які ми тут розглядали, хоча і більш складні, ніж наші власні користувацькі приклади.

Тому, коли ви використовували рядкові методи, такі як:

myString.split(',');

Ви використовували метод, доступний в екземплярі класу String. Кожного разу, створюючи рядок у своєму коді, цей рядок автоматично створюється як екземпляр String, і тому має декілька загальних  методів/властивостей, доступних на ньому.

Коли ви звертались до об'єктної моделі документа (DOM), використовуючи такі рядки:

var myDiv = document.createElement('div');
var myVideo = document.querySelector('video');

Ви використовували методи доступні в екземплярі класу Document. Для кожної завантаженої веб-сторінки створюється екземпляр Document, так званий document, який представляє структуру і зміст всієї сторінки, а також інші функції, такі як URL.

Те саме стосується і багатьох інших вбудованих об'єктів/API, які ви використовували — Array, Math, і т.д.

Зверніть увагу, що вбудовані об'єкти/API не завжди створюють екземпляри об'єктів автоматично. Наприклад, Notifications API, який дозволяє новим браузерам запускати системні повідомлення, вимагає, щоб ви створювали новий екземпляр об'єкта, за допомогою конструктора, для кожного повідомлення, яке ви хочете запустити. Спробуйте ввести наступне в консоль JavaScript:

var myNotification = new Notification('Hello!');

Ми розглянемо конструктори в наступній статті.

Заувага: Корисно подумати про те, як об'єкти взаємодіють шляхом передачі повідомлень - коли об'єкту потрібен інший об'єкт для виконання якої-небудь дії, він часто надсилає повідомлення іншому об'єкту, за допомогою одного з методів, і чекає відповіді, яку ми знаємо як повернене значення (return value).

Підсумок

Вітаємо, ви дійшли до завершення нашої першої статті про об'єкти в JS, тепер у вас має бути гарне уявлення про те, як працювати з об'єктами в JavaScript - в тому числі створювати свої власні прості об'єкти. Ви також повинні розуміти, що об'єкти дуже корисні в якості структур для зберігання пов'язаних даних і функціональності - якби ми намагались відстежувати всі властивості і методи в нашому об'єкті person як окремі змінні і функції, цу було б неефективно, і ми б ризикували зіткнутись з іншими змінними і функціями з такими ж іменами. Об'єкти дозволяють нам безпечно зберігати інформацію в своєму власному блоці, поза небезпекою.

У наступній статті ми почнемо розглядати теорію об'єктно-орієнтованого програмування (ООП), і як ці техніки можуть бути використані в JavaScript.

В цьому модулі

Мітки документа й учасники

Зробили внесок у цю сторінку: HelgeUa
Востаннє оновлена: HelgeUa,