Angularшлях до Strong Junior
🔥 0

Фундамент Ф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.

≈ 35 хв · +25 XP за урок