034.2 Урок 1
Сертифікат: |
Основи веброзробки |
---|---|
Версія: |
1.0 |
Розділ: |
034 JavaScript-програмування |
Тема: |
034.2 Структури даних JavaScript |
Урок: |
1 з 1 |
Вступ
Мови програмування, як і природні мови, представляють реальність за допомогою символів, які об’єднані у змістовні висловлювання. Реальність, представлена мовою програмування, – це машинні ресурси, такі як операції процесора, пристрої та пам’ять.
Кожна з безлічі мов програмування ухвалює парадигму представлення інформації. JavaScript приймає конвенції, типові для високорівневих мов, де більшість деталей, таких як розподіл пам’яті, є неявними, що дає змогу програмісту зосередитися на меті сценарію в контексті застосунку.
Мови програмування високого рівня
Мови програмування високого рівня забезпечують абстрактні правила, тому програмісту потрібно писати менше коду, щоб описати ідею. JavaScript пропонує зручні способи використання пам’яті комп’ютера, використовуючи концепції програмування, які спрощують написання повторюваних практик і яких, як правило, достатньо для цілей веброзробника.
Note
|
Хоча можна використовувати спеціалізовані механізми для ретельного доступу до пам’яті, простіші типи даних, які ми розглянемо, є більш прийнятими у використанні. |
Типові операції у вебзастосунку полягають у запиті даних за допомогою певної інструкції JavaScript і зберіганні їх для обробки та, зрештою, представлення користувачу. Це сховище є досить гнучким у JavaScript, з відповідними форматами зберігання для кожної мети.
Оголошення констант і змінних
Оголошення констант і змінних для зберігання даних є фундаментом будь-якої мови програмування. JavaScript приймає конвенцію більшості мов програмування, призначаючи значення константам або змінним із синтаксисом "ім’я = значення". Константа або змінна зліва приймає значення праворуч. Ім’я константи або змінної має починатися з літери або підкреслення.
Тип даних, що зберігаються у змінній, не потрібно вказувати, оскільки JavaScript є мовою динамічної типізації. Тип змінної визначається із присвоєного їй значення. Однак зручно позначити певні атрибути в оголошенні, щоб гарантувати очікуваний результат.
Note
|
TypeScript – це мова, натхненна JavaScript, яка подібно до мов нижнього рівня, дає змогу вам оголошувати змінні для певних типів даних. |
Константи
Константа – це символ, який призначається один раз під час запуску програми і ніколи не змінюється. Константи корисні для визначення фіксованих значень, наприклад, визначення константи PI
як 3,14159265 або COMPANY_NAME
, щоб зберігати назву вашої компанії.
У вебзастосунку, наприклад, розглянемо клієнта, який отримує інформацію про погоду з віддаленого сервера. Програміст може вирішити, що адреса сервера має бути постійною, оскільки вона не зміниться під час виконання програми. Однак інформація про температуру може змінюватися з кожним надходженням нових даних із сервера.
Інтервал між запитами, здійсненими до сервера, також можна визначити як константу, яку можна запитати з будь-якої частини програми:
const update_interval = 10;
function setup_app(){
console.log("Оновлювати кожні " + update_interval + "хвилин");
}
Після виклику функція setup_app()
відображає на консолі повідомлення "Оновлювати кожні 10 хвилин". Термін const
, розміщений перед іменем update_interval
, гарантує, що його значення залишиться незмінним протягом усього виконання сценарію. Якщо робиться спроба скинути значення константи, видається помилка TypeError: Assignment to constant variable
.
Змінні
Без терміна const
JavaScript автоматично припускає, що update_interval
є змінною, і що її значення можна змінити. Це еквівалентно явному оголошенню змінної за допомогою var
:
var update_interval;
update_interval = 10;
function setup_app(){
console.log("Оновлювати кожні " + update_interval + "хвилин");
}
Зауважте, що хоча змінна update_interval
була визначена поза функцією, доступ до неї був здійснений всередині функції. Будь-яка константа або змінна, оголошена за межами функцій або блоків коду, визначених фігурними дужками ({}
), має глобальну область видимості; тобто доступ до неї можна отримати з будь-якої частини коду. Протилежне невірно: константа або змінна, оголошена всередині функції, має локальну область видимості, тому доступ до неї є лише всередині самої функції. Блоки коду, розділені квадратними дужками, наприклад ті, що розміщені в структурах прийняття рішень if
або в циклах for
, розмежовують область дії констант, але не змінних, оголошених як var
. Наприклад, такий код буде дійсним:
var success = true;
if ( success == true )
{
var message = "Транзакція виконана успішно";
var retry = 0;
}
else
{
var message = "Транзакцію виконати не вдалось";
var retry = 1;
}
console.log(message);
Оператор console.log(message)
може отримати доступ до змінної message
, навіть якщо вона була оголошена в блоці коду структури if
. Але це було б не так, якби message
було константою, як показано в наступному прикладі:
var success = true;
if ( success == true )
{
const message = "Транзакція виконана успішно";
var retry = 0;
}
else
{
const message = "Транзакцію виконати не вдалось";
var retry = 1;
}
console.log(message);
У цьому випадку буде видано повідомлення про помилку типу ReferenceError: message is not defined
(повідомлення не визначене), і сценарій буде зупинено. Хоча це може здатися обмеженням, однак обмеження діапазону змінних і констант допомагає уникнути плутанини між інформацією, що обробляється в тілі сценарію, і в його різних блоках коду. Із цієї причини змінні, оголошені за допомогою let
замість var
, також обмежені в області дії блоками, розділеними дужками. Існують також інші тонкі відмінності між оголошенням змінної за допомогою var
або let
, але найбільш значуща з них стосується області дії змінної, як було розглянуто тут.
Типи значень
У більшості випадків програмісту не потрібно турбуватися про тип даних, що зберігаються у змінній, оскільки JavaScript автоматично визначає тип як один зі своїх примітивних типів під час першого присвоєння значення змінній. Однак деякі операції можуть бути специфічними для того чи іншого типу даних і можуть призвести до помилок, якщо їх використовувати безрозсудно. Крім того, JavaScript пропонує структуровані типи, які дають змогу об’єднати більше одного примітивного типу в один об’єкт.
Примітивні типи
Екземпляри примітивного типу відповідають традиційним змінним, які зберігають лише одне значення. Типи визначаються неявно, тому оператор typeof можна використовувати, щоб визначити, який тип значення зберігається у змінній:
console.log("Undefined variables are of type", typeof variable);
{
let variable = true;
console.log("Value `true` is of type " + typeof variable);
}
{
let variable = 3.14159265;
console.log("Value `3.14159265` is of type " + typeof variable);
}
{
let variable = "Text content";
console.log("Value `Text content` is of type " + typeof variable);
}
{
let variable = Symbol();
console.log("A symbol is of type " + typeof variable);
}
Цей скрипт відобразить на консолі, який тип змінної використовувався в кожному випадку:
undefined variables are of type undefined Value `true` is of type boolean Value `3.114159265` is of type number Value `Text content` is of type string A symbol is of type symbol
Зверніть увагу, що перший рядок намагається знайти тип неоголошеної змінної. Це призводить до того, що дана змінна буде ідентифікована як undefined
(невизначена). Тип symbol
є найменш інтуїтивним примітивом. Його мета – надати унікальне ім’я атрибута в об’єкті, коли немає необхідності визначати конкретне ім’я атрибута. Об’єкт – це одна зі структур даних, які ми розглянемо далі.
Структуровані типи
Хоча примітивних типів достатньо для написання простих підпрограм, існують недоліки їх виключного використання в більш складних програмах. Наприклад, програму для електронної комерції було б набагато складніше написати, оскільки програмісту потрібно було б знайти способи зберігання списків елементів і відповідних значень, використовуючи лише змінні з примітивними типами.
Структуровані типи спрощують завдання групування інформації однакового характеру в одній змінній. Наприклад, список товарів у кошику для покупок можна зберігати в одній змінній типу масив:
let cart = ['Milk', 'Bread', 'Eggs'];
Як показано в прикладі, масив елементів позначається квадратними дужками. У прикладі масив заповнювався трьома значеннями рядків, тому використовуються одинарні лапки. Змінні також можна використовувати як елементи в масиві, але в цьому випадку їх потрібно вказувати без лапок. Кількість елементів у масиві можна запитати за допомогою властивості length
:
let cart = ['Milk', 'Bread', 'Eggs'];
console.log(cart.length);
Число 3
буде відображатися у виводі на консоль. Нові елементи можна додати до масиву за допомогою методу push()
:
cart.push('Candy');
console.log(cart.length);
Цього разу відображатиметься сума 4
. До кожного елемента в списку можна отримати доступ за його числовим індексом, починаючи з 0
:
console.log(cart[0]);
console.log(cart[3]);
На консолі відображатиметься результат:
Milk Candy
Так само, як ви можете використовувати push ()
, щоб додати елемент, ви можете використовувати pop ()
, щоб видалити останній елемент з масиву.
Значення, що зберігаються в масиві, не обов’язково мають бути одного типу. Можна, наприклад, зберігати кількість кожного елемента поруч. Список покупок, подібний до попереднього прикладу, можна скласти так:
let cart = ['Milk', 1, 'Bread', 4, 'Eggs', 12, 'Candy', 2];
// Індекси товарів парні
let item = 2;
// Індекси величин непарні
let quantity = 3;
console.log("Item: " + cart[item]);
console.log("Quantity: " + cart[quantity]);
Результат, який відображається на консолі після запуску цього коду:
Item: Bread Quantity: 4
Як ви, можливо, вже помітили, об’єднання назв товарів з їх відповідними кількостями в одному масиві може бути не дуже гарною ідеєю, оскільки зв’язок між ними не чітко виражений у структурі даних і дуже схильні до людських помилок. Навіть якби один масив використовувався для імен, а інший масив – для кількостей, підтримка цілісності списку вимагала б такої ж обережності і була б не дуже продуктивною. У таких ситуаціях найкращою альтернативою є використання більш відповідної структури даних: об’єкт.
У JavaScript структура даних об’єктного типу дає змогу прив’язувати властивості до змінної. Крім того, на відміну від масиву, елементи, що утворюють об’єкт, не мають фіксованого порядку. Елементом списку покупок, наприклад, може бути об’єкт із властивостями name
та quantity
:
let item = { name: 'Milk', quantity: 1 };
console.log("Item: " + item.name);
console.log("Quantity: " + item.quantity);
Цей приклад показує, що об’єкт можна визначити за допомогою дужок ({}
), де кожна пара властивість/значення розділяється двокрапкою, а ці властивості розділяються комами. Властивість доступна у форматі змінна.властивість, як у item.name
, як для читання, так і для призначення нових значень. Результат, який відображається на консолі після запуску цього коду:
Item: Milk Quantity: 1
Нарешті, кожен об’єкт, що представляє товар, може бути включений до масиву списку покупок. Це можна зробити безпосередньо під час створення списку:
let cart = [{ name: 'Milk', quantity: 1 }, { name: 'Bread', quantity: 4 }];
Як і раніше, новий об’єкт, що представляє елемент, може бути доданий пізніше до масиву:
cart.push({ name: 'Eggs', quantity: 12 });
Тепер доступ до елементів у списку здійснюється за індексом і назвою властивості:
console.log("Third item: " + cart[2].name);
console.log(cart[2].name + " quantity: " + cart[2].quantity);
Результат, який відображається на консолі після запуску цього коду:
third item: eggs Eggs quantity: 12
Структури даних дають змогу програмісту тримати свій код найбільш організованим і легшим в обслуговуванні, чи то оригінальним автором, чи іншими програмістами в команді. Крім того, багато вихідних даних функцій JavaScript мають структуровані типи, які повинні належним чином оброблятися програмістом.
Оператори
Поки що ми здебільшого бачили лише те, як призначати значення новоствореним змінним. Це просто, але будь-яка програма має виконувати чимало інших маніпуляцій зі значеннями змінних. JavaScript пропонує кілька типів операторів, які можуть діяти безпосередньо на значення змінної або зберігати результат операції в новій змінній.
Більшість операторів орієнтовані на арифметичні операції. Наприклад, щоб збільшити кількість товару в списку покупок, просто скористайтеся оператором додавання +
:
item.quantity = item.quantity + 1;
У наведеному нижче фрагменті друкується значення item.quantity
до та після додавання. Не плутайте ролі знака «+» у цьому фрагменті. У операторах console.log
використовується знак плюс для поєднання двох рядків.
let item = { name: 'Milk', quantity: 1 };
console.log("Item: " + item.name);
console.log("Quantity: " + item.quantity);
item.quantity = item.quantity + 1;
console.log("New quantity: " + item.quantity);
Результат, який відображається на консолі після запуску цього коду:
Item: Milk Quantity: 1 New quantity: 2
Зверніть увагу, що значення, раніше збережене в item.quantity
, використовується як операнд операції додавання:` item.quantity = item.quantity + 1`. Лише після завершення операції значення в item.quantity
оновлюється результатом цієї операції. Цей вид арифметичної операції, який залучає поточне значення цільової змінної, є досить поширеним, тому існують скорочені оператори, які дають змогу записати ту ж операцію в скороченому форматі:
item.quantity += 1;
Інші основні операції також мають еквівалентні скорочені оператори:
-
a = a - b
еквівалентноa -= b
. -
a = a * b
еквівалентноa *= b
. -
a = a / b
еквівалентноa /= b
.
Для додавання та віднімання доступний третій формат, коли другий операнд є лише одним блоком:
-
a = a + 1
еквівалентноa++
. -
a = a - 1
еквівалентноa--
.
В одній операції можна об’єднати більше одного оператора, а результат можна зберегти в новій змінній. Наприклад, у наступному операторі розраховується загальна ціна товару плюс вартість доставки:
let total = item.quantity * 9.99 + 3.15;
Порядок виконання операцій дотримується традиційних правил пріоритету: спочатку виконуються операції множення і ділення, і лише потім виконуються операції додавання і віднімання. Оператори з однаковим пріоритетом виконуються в порядку їх появи у виразі, зліва направо. Щоб змінити порядок пріоритету за замовчуванням, ви можете використовувати дужки, як у a * (b + c)
.
У деяких ситуаціях результат операції навіть не потрібно зберігати у змінній. Це той випадок, коли ви хочете оцінити результат виразу в операторі if
:
if ( item.quantiy % 2 == 0 )
{
console.log("Кількість цього товару парна");
}
else
{
console.log("Кількість цього товару непарна");
}
Оператор %
(по модулю) повертає залишок від поділу першого операнда на другий операнд. У цьому прикладі оператор if перевіряє, чи дорівнює нулю залишок від ділення item.quantity
на 2, тобто чи кратна двум item.quantity
.
Коли один з операндів оператора +
є рядком, інші оператори примусово трансформуються у рядки, і результатом є конкатенація рядків. У попередніх прикладах цей тип операції використовувався для конкатенації рядків і змінних в аргумент оператора console.log
.
Це автоматичне перетворення може бути небажаною поведінкою. Наприклад, введене користувачем значення в полі форми може бути ідентифіковано як рядок, тоді як насправді це числове значення. У таких випадках змінну потрібно спочатку перетворити в число за допомогою функції Number()
:
sum = Number(value1) + value2;
Крім того, важливо переконатися, що користувач надав дійсне значення, перш ніж продовжити операцію. У JavaScript змінна без присвоєного значення містить значення null
. Це дає змогу програмісту використовувати такий оператор прийняття рішення, як if ( value1 == null )
, щоб перевірити, чи було присвоєно значення змінній, незалежно від типу значення, призначеного цій змінній.
Вправи до посібника
-
Масив – це структура даних, наявна в різних мовах програмування, деякі з яких допускають лише масиви з елементами одного типу. У випадку JavaScript, чи можна визначити масив з елементами різних типів?
-
На основі прикладу
let item = { name: 'Milk', quantity: 1 }
для об’єкта в списку покупок, як цей об’єкт можна оголосити, щоб включити також ціну товару? -
Які є способи оновлення значення змінної до половини її поточного значення в одному рядку коду?
Дослідницькі вправи
-
У наступному коді яке значення буде відображатися у виводі консолі?
var value = "Global"; { value = "Location"; } console.log(value);
-
Що станеться, якщо один або кілька операндів, які беруть участь в операції множення, є рядком?
-
Як можна видалити елемент
Eggs
з масивуcart
, оголошеного за допомогоюlet cart = ['Milk', 'Bread', 'Eggs']
?
Підсумки
Цей урок охоплює базове використання констант і змінних у JavaScript. JavaScript є мовою з динамічною типізацією, тому програмісту не потрібно вказувати тип змінної перед встановлення її значення. Однак важливо знати примітивні типи мови, щоб забезпечити правильний результат основних операцій. Крім того, структури даних, такі як масиви та об’єкти, поєднують примітивні типи і дають змогу програмісту створювати складніші, складені змінні. Цей урок розглядає наступні концепції та процедури:
-
Розуміння концепцій констант і змінних.
-
Область видимості змінної.
-
Оголошення змінних за допомогою
var
та` let` . -
Примітивні типи.
-
Арифметичні оператори.
-
Масиви та об’єкти.
-
Примусове перетворення типів і перетворення типів.
Відповіді до вправ посібника
-
Масив – це структура даних, наявна в різних мовах програмування, деякі з яких допускають лише масиви з елементами одного типу. У випадку JavaScript, чи можна визначити масив з елементами різних типів?
Так, у JavaScript можна визначати масиви з елементами різних примітивних типів, такими як рядки та числа.
-
На основі прикладу
let item = { name: 'Milk', quantity: 1 }
для об’єкта в списку покупок, як цей об’єкт можна оголосити, щоб включити також ціну товару?let item = { name: 'Milk', quantity: 1, price: 4.99 };
+
Можна використовувати саму змінну як операнд, value = value / 2
, або скорочений оператор /=
: value /= 2
.
Відповіді до дослідницьких вправ
-
У наступному коді яке значення буде відображатися у виводі консолі?
var value = "Global"; { value = "Location"; } console.log(value);
Location
-
Що станеться, якщо один або кілька операндів, які беруть участь в операції множення, є рядком?
JavaScript призначить результату значення
NaN
(Not a Number, не число), що вказує на те, що операція недійсна. -
Як можна видалити елемент
Eggs
з масивуcart
, оголошеного за допомогоюlet cart = ['Milk', 'Bread', 'Eggs']
?Масиви в javascript мають метод
pop ()
, який видаляє останній елемент у списку:cart.pop()
.