Фундамент Ф1 · урок 3 з 12
Функції
Функція — шматок коду з імʼям, який можна викликати скільки завгодно разів і щоразу з іншими
даними. На функціях стоїть усе: обробник кліку — функція, метод компонента — функція, computed(() => …)
у сигналах — теж функція. А ще в JavaScript функцію можна передати іншій функції, як звичайне значення. Без цього
не зрозуміти ні методів масивів, ні подій, ні RxJS — тому цей урок варто прочитати уважно.
Оголошення й виклик
function greet(name) { // name — параметр: імʼя для вхідного значення
return `Привіт, ${name}!`; // return — що функція віддає назад
}
greet('Оля'); // 'Привіт, Оля!' — 'Оля' тут аргумент
greet('Тарас'); // той самий код, інші дані
Параметр — змінна, яка існує лише всередині функції й отримує значення в момент виклику. Те, що
передаєш при виклику, називають аргументом. return робить дві речі: віддає значення тому,
хто викликав, і одразу завершує функцію — рядки після нього не виконаються. Функція без
return повертає undefined.
Дужки після імені — це і є виклик. greet без дужок — сама функція як значення,
greet('Оля') — результат її роботи. Запамʼятай цю різницю: вона знадобиться за хвилину.
Параметри за замовчуванням
function formatPrice(amount, currency = 'грн') {
return `${amount} ${currency}`;
}
formatPrice(250); // '250 грн'
formatPrice(10, '$'); // '10 $'
Якщо аргумент не передали, параметр отримує undefined — або значення за замовчуванням, якщо його
вказано.
Функція — теж значення
Функцію можна покласти в змінну, як число чи рядок, і передати іншій функції. Функцію, яку передають, щоб її викликали потім або для кожного елемента, називають колбеком (callback — «зворотний виклик»).
function repeat(times, action) {
for (let i = 1; i <= times; i++) {
action(i); // викликаємо те, що нам передали
}
}
function shout(n) {
console.log(`Крок ${n}!`);
}
repeat(3, shout); // передаємо саму функцію — без дужок!
Зверни увагу: repeat(3, shout), а не repeat(3, shout()). З дужками ти викликав би
shout одразу й передав би repeat її результат — undefined. А потім
repeat спробувала б викликати undefined — і впала б.
Саме так влаштовані tasks.filter(…), button.addEventListener('click', …) і
stream.subscribe(…): ти передаєш функцію, а викликає її хтось інший тоді, коли треба.
Запусти. Потім заміни repeat(3, shout) на repeat(3, shout()) —
і подивись, яку помилку покаже пісочниця.
Стрілкові функції
Для коротких функцій є коротший запис — стрілковий. Він трапляється в Angular-коді частіше за звичайний:
// звичайна
function double(x) {
return x * 2;
}
// стрілкова — те саме
const double2 = (x) => x * 2;
// один параметр — дужки можна не писати
const triple = x => x * 3;
// кілька рядків — фігурні дужки і return обовʼязкові
const describe = (title, done) => {
const status = done ? 'готово' : 'в роботі';
return `${title}: ${status}`;
};
Правило, на якому спотикаються всі: без фігурних дужок значення повертається саме, з фігурними —
лише через return. А якщо стрілка має повернути обʼєкт, його беруть у круглі дужки:
() => ({ done: true }). Без них фігурні дужки сприймуться як тіло функції.
Найчастіше стрілки живуть саме колбеками: repeat(3, n => console.log(n)) — функцію
оголошено прямо в місці передачі. Ще одна відмінність стрілок — поведінка this — стане важливою
в уроці про класи.
Для завдання знадобиться Math.round(x) — округлення до найближчого цілого:
Math.round(33.3) — це 33, Math.round(66.7) — 67.
Допиши функцію percent(done, total): вона повертає відсоток виконаного,
округлений до цілого. Подивись на останній виклик: у порожньому списку total — нуль, а ділити на
нуль не можна. Для такого випадку функція має повертати 0.
if (total === 0) return 0;, а потім
return Math.round(done / total * 100);Чисті функції
Функція чиста, якщо її результат залежить лише від аргументів і вона нічого не змінює поза собою:
не пише в зовнішні змінні, не змінює переданих обʼєктів, не ходить у мережу. percent — чиста: з тими
самими числами завжди той самий результат. Таку функцію легко тестувати й безпечно викликати скільки завгодно
разів.
Решта — побічні ефекти: запис у localStorage, вивід у консоль, запит на сервер. Вони
потрібні, але їх тримають окремо. В Angular цю межу видно прямо: computed має бути чистим
обчисленням, а побічні дії живуть в effect — це урок про сигнали в модулі 2.
Підняття (hoisting) — коротко
Функцію, оголошену через function name() {}, можна викликати навіть вище за рядок, де її
написано: JavaScript «піднімає» такі оголошення на початок. Стрілку в const — ні: до свого рядка вона
ще не існує, і буде помилка Cannot access … before initialization.
- Забутий
return— функція «нічого не повертає», тобто повертаєundefined. - Стрілка з фігурними дужками без
return:(a, b) => { a + b }повертаєundefined. - Виклик замість передачі:
addEventListener('click', save())викликаєsaveодразу, а не на клік. - Обʼєкт зі стрілки без круглих дужок:
() => { done: true }повертаєundefined.
Підсумок
- Параметр — змінна всередині функції, аргумент — те, що передали при виклику.
returnповертає й завершує. fn— сама функція,fn()— її результат. Колбеки передають без дужок.- Стрілка без фігурних дужок повертає значення сама, з фігурними — лише через
return. - Чисті функції залежать лише від аргументів і нічого не змінюють навколо — саме такі потрібні в
computed.