Об’єкти JavaScript, квадратні дужки та алгоритми

Одним з найпотужніших аспектів JavaScript є можливість динамічного посилання на властивості об’єктів. У цій статті ми розглянемо, як це працює, і які переваги це може дати нам. Ми швидко розглянемо деякі структури даних, що використовуються в інформатиці. Крім того, ми розглянемо щось, що називається Big O notation, яке використовується для опису продуктивності алгоритму.

Вступ до об’єктів

Почнемо зі створення простого об'єкта, що представляє автомобіль. Кожен об’єкт має щось, що називається properties. Властивість - це змінна, яка належить об’єкту. Наш об'єкт машина матиме три властивості: make, modelі color.

Давайте подивимось, як це може виглядати:

const car = { make: 'Ford', model: 'Fiesta', color: 'Red'};

Ми можемо посилатися на окремі властивості об’єкта, використовуючи крапкові позначення. Наприклад, якщо ми хотіли з’ясувати, якого кольору наш автомобіль, ми можемо скористатися таким позначенням крапок car.color.

Ми могли б навіть вивести це за допомогою console.log:

console.log(car.color); //outputs: Red

Іншим способом посилання на властивість є використання квадратних дужок:

console.log(car['color']); //outputs: Red

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

Тобто, замість жорсткого кодування конкретного імені властивості, ми можемо вказати його як рядок у змінній:

const propertyName = 'color';const console.log(car[propertyName]); //outputs: Red

Використання динамічного пошуку з позначеннями в квадратних дужках

Давайте розглянемо приклад, де ми можемо це використовувати. Скажімо, ми управляємо рестораном і хочемо мати змогу дізнатись ціни на продукти, які є в нашому меню. Один із способів зробити це - використання if/elseоператорів.

Давайте напишемо функцію, яка прийме назву товару та поверне ціну:

function getPrice(itemName){ if(itemName === 'burger') { return 10; } else if(itemName === 'fries') { return 3; } else if(itemName === 'coleslaw') { return 4; } else if(itemName === 'coke') { return 2; } else if(itemName === 'beer') { return 5; }}

Хоча вищевказаний підхід працює, він не ідеальний. У нашому коді ми жорстко закодували меню. Тепер, якщо наше меню зміниться, нам доведеться переписати наш код і перерозподілити його. Крім того, ми могли б мати довге меню, і писати весь цей код було б громіздко.

Кращим підходом було б розділити наші дані та нашу логіку. Дані будуть містити наше меню, і логіка буде шукати ціни з цього меню.

Ми можемо представити menuяк об’єкт, де ім’я властивості, також відоме як ключ, відповідає значенню.

У цьому випадку ключем буде назва товару, а значенням буде ціна товару:

const menu = { burger: 10, fries: 3, coleslaw: 4, coke: 2, beer: 5};

Використовуючи нотацію в квадратних дужках, ми можемо створити функцію, яка прийме два аргументи:

  • об'єкт меню
  • рядок з назвою елемента

і повернути ціну цього товару:

const menu = { burger: 10, fries: 3, coleslaw: 4, coke: 2, beer: 5};
function getPrice(itemName, menu){ const itemPrice = menu[itemName]; return itemPrice;}
const priceOfBurger = getPrice('burger', menu);console.log(priceOfBurger); // outputs: 10

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

Структури даних та алгоритми

Карта в термінах Комп’ютерних наук - це структура даних, яка являє собою набір пар ключ / значення, де кожен ключ відображає відповідне значення. Ми можемо використовувати його для пошуку значення, яке відповідає певному ключу. Це те, що ми робимо в попередньому прикладі. У нас є ключ, який є назвою товару, і ми можемо знайти відповідну ціну цього товару, використовуючи наш об’єкт меню. Ми використовуємо об’єкт для реалізації структури даних карти.

Давайте розглянемо приклад, чому ми можемо захотіти використовувати карту. Скажімо, у нас є книжковий магазин і є список книг. Кожна книга має унікальний індентифікатор, який називається Міжнародний стандартний номер книги (ISBN), що є 13-значним числом. Ми зберігаємо наші книги в масиві і хочемо мати можливість шукати їх за допомогою ISBN.

Один із способів зробити це, перебираючи масив, перевіряючи значення ISBN кожної книги, і якщо воно відповідає його поверненню:

const books = [{ isbn: '978-0099540946', author: 'Mikhail Bulgakov', title: 'Master and Margarita'}, { isbn: '978-0596517748', author: 'Douglas Crockford', title: 'JavaScript: The Good Parts'}, { isbn: '978-1593275846', author: 'Marijn Haverbeke', title: 'Eloquent JavaScript'}];
function getBookByIsbn(isbn, books){ for(let i = 0; i < books.length; i++){ if(books[i].isbn === isbn) { return books[i]; } }}
const myBook = getBookByIsbn('978-1593275846', books);

Це добре працює в цьому прикладі, оскільки у нас є лише три книги (це невеликий книжковий магазин). Однак, якби ми були Amazon, перегляд мільйонів книг міг би бути дуже повільним та обчислювально дорогим.

Позначення Big O використовується в Computer Science для опису роботи алгоритму. Наприклад, якщо n - кількість книг у нашій колекції, вартість використання ітерації для пошуку книги в найгіршому випадку (книга, яку ми шукаємо, остання в списку) буде O (n) . Це означає, що якщо кількість книг у нашій колекції подвоїться, вартість пошуку книги за допомогою ітерації також подвоїться.

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

Як обговорювалося, для пошуку значення, яке відповідає ключу, можна використовувати карту. Ми можемо структурувати наші дані як карту, а не як масив, використовуючи об’єкт.

Ключем буде ISBN, а значенням буде відповідний об’єкт книги:

const books = { '978-0099540946':{ isbn: '978-0099540946', author: 'Mikhail Bulgakov', title: 'Master and Margarita' }, '978-0596517748': { isbn: '978-0596517748', author: 'Douglas Crockford', title: 'JavaScript: The Good Parts' }, '978-1593275846': { isbn: '978-1593275846', author: 'Marijn Haverbeke', title: 'Eloquent JavaScript' }};
function getBookByIsbn(isbn, books){ return books[isbn];}
const myBook = getBookByIsbn('978-1593275846', books);

Замість того, щоб використовувати ітерацію, тепер ми можемо використовувати простий пошук карти за ISBN, щоб отримати наше значення. Нам більше не потрібно перевіряти значення ISBN для кожного об’єкта. Ми отримуємо значення безпосередньо з карти за допомогою ключа.

Що стосується продуктивності, пошук карти забезпечить значне поліпшення порівняно з ітерацією. Це пояснюється тим, що пошук карти має постійні витрати з точки зору обчислень. Це можна записати, використовуючи позначення Big O як O (1) . Немає значення, чи є у нас три-три мільйони книг, ми можемо отримати книгу, яку хочемо, так само швидко, виконавши пошук карти за допомогою ключа ISBN.

Підсумок

  • We have seen we can access the values of object properties using dot notation and square bracket notation
  • We learned how we can dynamically look up values of property by using variables with square bracket notation
  • We have also learned that a map datastructure maps keys to values. We can use keys to directly look up values in a map which we implement using an object.
  • We had a first glance at how algorithm performance is described using Big O notation. In addition, we saw how we can improve the performance of a search by converting an array of objects into a map and using direct lookup rather than iteration.

Want to test your new found skills? Try the Crash Override exercise on Codewars.

Want to learn how to write web applications using JavaScript? I run Constructor Labs, a 12 week JavaScript coding bootcamp in London. The technologies taught include HMTL, CSS, JavaScript, React, Redux, Node and Postgres. Everything you need to create an entire web app from scratch and get your first job in the industry. Fees are £3,000 and next cohort starts on 29th May. Applications are open now.