Об'єкти

javascript.ru/tutorial/object/intro.

learn.javascript.ru/object.

Тип даних об'єкт

Об’єкт за своєю суттю нагадує масив: він містить набір елементів довільного типу.

Відмінності полягають в тому, що елементи не пронумеровані (та не сортовані), а мають ключі. Тобто, до елементів об’єкту звертатися потрібно не по індексу, а по ключу. Порядок ключів у об'єкті немає значення, при виводі в консоль ключі для зручності сортуються в алфавітному порядку.

Іншими словами, об'єкт - це набір змінних (та функцій), об'єднаних одним іменем.

Об'єкт складається з властивостей (properties, keys) та методів. Ще кажуть: з пар "ключ - значення". Методи розглянемо пізніше.

Наведіть приклади об'єктів з життя, опишіть їх властивості.

Створення об'єкта:

let a = {};
let b = { name: 'Маша', age: 17 };
let c = {'0':[1,2,3],'1':b,'привіт':'пока'};
let car = {
  'марка': 'ЗАЗ',
  'модель': '969',
  doors: 2,
  power: '30 к.с.'
};
console.dir(a);
console.dir(b);
console.dir(c);
console.dir(car);
console.dir({});

Об'єкт огортається у фігурні скобки. Після об'єкта ставиться крапка з комою. Ключ та значення розділяються двокрапкою. Властивості розділяються комою.

Робота з властивостями об'єкта

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

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

Якщо властивість має в собі кириличні символи - бажано також використовувати квадратні дужки.

car.power = '38 к.с.';
console.log('У машини ' + car.doors + ' дверей');
alert(car['марка']);
car['модель'] = '969м';

Якщо вказати неіснуючий ключ, то він буде створений, тобто, до об'єкта добавиться нова властивість:

car.color = 'rgba(255, 0, 0, 0.5)';
car['gear lever'] = 'Трояндочка в епоксидці';
console.log(car);

Властивості можна видаляти командою delete:

delete car.door;
delete car['color'];
console.log(car);

Перебір властивостей, копіювання об'єктів

Для того, щоб перебрати всі властивості об'єкта, є спеціальний формат цикла for:

let obj = { ... };
for (let key in obj) {
  console.log(key, '=', obj[key]);
}

Цикл по черзі перебирає всі властивості об'єкта. На кожній ітерації у змінну key записується назва властивості, а значення властивості доступне як obj[key].

Об'єкти, як і масиви, у змінних зберігають лише адресу на комірку пам'яті, тому копіювати напряму їх не можна:

let a = { ... };
let b = a;    // у змінних a та b буде зберігатися один і той самий об'єкт

Для копіювання об'єкта його треба перебрати та всі значення занести у новий об'єкт:

let a = { ... };
let b = {};
for (let key in a) {
  b[key] = a[key];
}

Якщо властивості об'єкта містять складні структури даних (інші об'єети, масиви), то перебір потрібно здійснювати рекурсивно. Про рекурсію буде одна з наступних тем.

Об'єкти як аргументи функцій та повернення результату

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

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

function setCSS(element, color, fs, bg) {
  element.style.color = color;
  element.style.fontSize = fs;
  element.style.backgroundColor = bg;
}

let css = {
  color: '...',
  fs: '...',
  bg: '...'
}
function setCSS(element, styles) {
  element.style.color = styles.color;
  element.style.fontSize = styles.fs;
  element.style.backgroundColor = styles.bg;
}

Якщо треба повертати декілька значень - їх зручно загнати в об'єкт, а не в масив, та повернути:

function fun(){
  let res = {};
  res.x = ...;
  res.y = ...
  return res;
}
console.log( fun().x );
let c = fun();
alert( c.x + ', ' + c.y );

Приклад локалізації та задача про типи даних

Для локалізації та подібних задач зручно робити словники:

let eng = {
  'привіт': 'hello',
  'як ся маєш?': 'how are you?',
  'бувай': 'good bye'
};

Тепер локалізуємо текст:

<p>привіт</p>
<p>як ся маєш?</p>
<p>бувай</p>

let p = document.getElementsByTagName('p');
for (let i = 0; i < p.length; i++) {
  p[i].innerText = eng[p[i].innerText];
}

В задачі про видачу типів даних українською мовою можна використати той же принцип:

створюємо словник відповідностей typeof та українських назв;
ретурнимо значення типу ukr[typeof Ї];

Домашнє завдання

  1. Створіть об'єкт з інформацією про себе: ім'я, прізвище, кількість копійок в кишені).
  2. Добавте властивість "дата народження" (кирилицею) в форматі дд.мм.рррр
  3. Добавте властивість age2033, в яку запишіть число, розрахувавши скільки вам буде років у 2033 році.
  4. Добавте циклом властивості про ваш вік у 2010-2020 роках.
  5. Переберіть циклом всі властивості та виведіть їх в консоль у вигляді: 0 name Бобир
    1 fname Олександр
    2 coins 75
    3 дата народження 05.10.1982
    ...
  6. Видаліть властивість про вміст кишені.
  7. Скопіюйте об'єкт з інформацією про себе, всі строкові значення продублюйте ("Бобир" --> "БобирБобир"), а числові - помножте на два (75 --> 150); виведіть обидва об'єкта.
  8. Створіть функцію розрахунку об'єму коробки яка приймає один аргумент у вигляді об'єкта. Функція повинна повертати два числових значення: в кубічних сантиметрах та літрах (см3 та дм3);
  9. Створіть функцію, що повертає об'єкти про користувачів, зчитуючи їх з форми: login, e-mail, phone, role (admin, moderator, user, viewer); створіть масив з 5 користувачів та виведіть його в консоль.
  10. Локалізацію деяких елементів веб-сторінки покладено на фронтенд.
    Наразі сайт має базову українську мову та дві локалізації - англійську та російську.
    Бекенд добавляє у тег body атрибут data-lang зі значенням en або ru.
    Технічне завдання: Зробіть скриптом локалізацію на англійську мову. HTML-код: table { width: 400px; border-collapse: collapse;}
    th, td { padding: 8px; border: 1px solid silver;}
    th { text-align: left;}
    th, .total { font-size: 120%; line-height: 1.3em; font-weight: bold;}
    th:nth-child(3),
    td:nth-child(3),
    .total td:nth-child(2) { text-align: right;}

    <h2><span>Корзина</span></h2>
    <table>
      <tr>
        <th><span>Товар</span></th>
        <th><span>Кількість</span></th>
        <th><span>Ціна</span></th>
      </tr>
      <tr>
        <td><strong>Adapter 220/12 euro</strong>:</td>
        <td>2 <span>шт.</span></td>
        <td><em>40 <span>грн.</span></td>
      </tr>
      <tr>
        <td><strong>Cable 5A</strong>:</td>
        <td>7 <span>м.</span></td>
        <td><em>8 <span>грн.</span></td>
      </tr>
      <tr>
        <td><strong>Socket 2x 16A white</strong>:</td>
        <td>1 <span>шт.</span></td>
        <td><em>40 <span>грн.</span></td>
      </tr>
      <tr class="total">
        <td colspan="2">Загальна сума:</td>
        <td><em>320 <span>грн.</span></em></td>
      </tr>
    </table>
    Вказівки до виконання:
    В першу чергу складіть алгоритм.
    Оскільки є дві мови - потрібно створити два словника.
    Щоб дізнатися яку мову встановив бекенд - задайте потрібний атрибут та дослідіть вміст елемента document.body.

 

 

Відео CS50. Лекция #18. JavaScript [Гарвард, Основы программирования, осень 2015 год].

Курс CS50 українською.