Към съдържанието
wannacode

Параметри и return

Проблем

Една бележка, различни суми

Искаш функция, която печата последния ред на бележката: „Общо: … €“. Но сумата е различна за всяка поръчка.

Функциите от миналия урок печатат винаги едно и също. Функция printTotal() няма откъде да знае сумата. Не искаш и функции за всяка сума поотделно. Трябва начин да подадеш сумата на функцията, когато я викаш.

Идеята

Параметри: какво получава функцията

Напиши в скобите име за това, което функцията очаква. Това е параметър. Вътре във функцията той е обикновена променлива.

При извикването слагаш в скобите стойността. Тя се казва аргумент.

function printTotal(total) {
console.log(`Общо: ${total} €`);
}
printTotal(12.5);
printTotal(4.2);
Изход
Общо: 12.5 €
Общо: 4.2 €

total е параметърът. 12.5 и 4.2 са аргументите. Функцията е една, а печата различни суми.

Тип пред параметъра не се пише: JavaScript не проверява какво подаваш. Ако подадеш текст вместо число, функцията ще го отпечата, без да се оплаче. Затова името на параметъра трябва да казва ясно какво се очаква.

Ако параметрите са няколко, разделяш ги със запетая. Аргументите се подават в същия ред.

Пробвай

По място, не по име

Какво ще отпечата програмата?

function printLine(item, qty) {
console.log(`${item}: ${qty} бр.`);
}
const coffee = "Кафе";
const qty = 3;
printLine(coffee, 2);
Отговор

Проблем

Защо цената не се намали?

Написал си функция за 10% отстъпка и си я извикал:

function applyDiscount(price) {
price = price * 0.9;
}
const price = 100;
applyDiscount(price);
console.log(price); // 100
Изход
100

Цената пак е 100. Функцията не дава грешка, а отстъпката я няма. Къде отиде?

Виж го

Функцията получава копие

function applyDiscount(price) {
price = price * 0.9;
}
const price = 100;
applyDiscount(price);
console.log(price); // 100
Стъпка по стъпка, с думи
  1. В програмата има променлива price = 100.
  2. Викаш applyDiscount(price): за функцията се заделя нова памет.
  3. Стойността се копира в нейния параметър price.
  4. Функцията намалява своето копие: 100 * 0.9 = 90.
  5. Функцията свършва и паметта ѝ изчезва, заедно с копието.
  6. А price в програмата си е 100.

При извикването функцията не получава самата променлива price, а копие на стойността ѝ. Тя намалява копието. Когато функцията свърши, паметта ѝ изчезва, а с нея и копието. Това се казва предаване по стойност.

Двете променливи се казват еднакво (price) нарочно: точно това обърква на практика. Името няма значение, всяка функция има своите променливи.

По-точно, за любопитните

В JavaScript аргументите винаги се предават по стойност. При масивите и обектите се копира връзката към тях, затова промените, направени във функцията, се виждат и отвън:

function addItem(items) {
items.push("мляко");
}
const cart = ["хляб"];
addItem(cart);
console.log(cart);
Изход
[ 'хляб', 'мляко' ]

Обектите ще видим в модул „Класове и обекти“.

Идеята

return: функцията връща резултат

Поправката е функцията да върне новата цена. В тялото пишеш return и стойността. Тип на резултата не се пише: function е същото, независимо дали функцията връща нещо.

function applyDiscount(price) {
return price * 0.9;
}
let price = 100;
price = applyDiscount(price);
console.log(price); // 90
Стъпка по стъпка, с думи
  1. В програмата: price = 100.
  2. Викаш applyDiscount(price): заделя се памет за функцията.
  3. Стойността се копира в параметъра price.
  4. return price * 0.9: резултатът е 90.
  5. Резултатът се връща в програмата и се записва в price.
  6. Сега price в програмата е 90.

Извикването applyDiscount(price) вече е стойност. Можеш да я запишеш в променлива (както тук), да я отпечаташ или да смяташ с нея.

По-точно, за любопитните
  • Функция без return също връща нещо: undefined, стойността „нищо“. Ако отпечаташ резултата на първата версия, която само намаляваше своето копие, ще видиш точно това:
function applyDiscount(price) {
price = price * 0.9;
}
console.log(applyDiscount(100));
Изход
undefined
  • Може да пишеш и return без стойност. Той просто приключва функцията.
  • Функцията може да върне няколко стойности наведнъж в масив, а при извикването ги разпределяш в отделни променливи със скоби [ ]:
function getLimits() {
return [1, 10];
}
const [low, high] = getLimits();
console.log(low, high);
Изход
1 10

Пробвай

Какъв е резултатът?

Функцията смята ДДС от 20% върху цената. Какво трябва да пише на празното място, за да получи резултата този, който я вика?

function vat(price) {
   price * 0.2;
}

Пробвай

Върнато, но изгубено

Какво ще отпечата програмата?

function reserve(seats) {
seats = seats - 2;
console.log(`вътре: ${seats}`);
return seats;
}
const seats = 10;
reserve(seats);
console.log(`отвън: ${seats}`);
Отговор

Идеята

return приключва функцията

Магазинът не взима доставка за поръчки от 50 € нагоре. Иначе доставката е 4,99 €:

function shippingCost(total) {
if (total >= 50) {
return 0;
}
return 4.99;
}
console.log(shippingCost(62.0));
console.log(shippingCost(18.5));
Изход
0
4.99

Щом стигне до return, функцията свършва веднага. Затова при 62 € вторият return не се изпълнява и не ни трябва else.

Функция с резултат трябва да върне стойност по всеки път. Но JavaScript не го проверява. Ако махнеш последния ред, програмата върви, а за поръчка от 18,50 € функцията стига до края си без return и връща undefined:

function shippingCost(total) {
if (total >= 50) {
return 0;
}
}
console.log(shippingCost(62.0));
console.log(shippingCost(18.5));
Изход
0
undefined

Грешка няма, затова такъв пропуск се хваща трудно. Гледай изхода и пробвай всеки път през функцията.

Пробвай

Намери грешката

Членовете на клуба имат 10% отстъпка, останалите плащат пълната цена. Но отстъпка получават всички. На кой ред е грешката?

Избери реда с грешката.

Упражнение

Функции, които смятат

Реши задачите в редактора си. Всяка функция получава каквото ѝ трябва като параметри и връща резултата. Печата се извън функциите, в редовете под тях.

1. Средно аритметично. Функция average(values) връща средното на числата в масива. Под нея прочети от клавиатурата колко са числата, после самите числа.

Вход
5
10
15
20
25
30
Изход
Средно аритметично: 20

2. Просто число. Функция isPrime(n) връща дали числото е просто (дели се само на 1 и на себе си). За 7 връща true, за 12 false.

3. Температури. Функции toFahrenheit(c) и toCelsius(f). F = C · 9 / 5 + 32. Прочети температура и мерна единица (C или F) и отпечатай превърнатата.

Вход
100
C
Изход
100 C = 212 F

4. Калкулатор. Функция calculate(a, b, op) връща резултата за +, -, * или /. Операцията се избира с if.

Вход
10
5
+
Изход
10 + 5 = 15

5. Триъгълник с параметър. Обещахме го в миналия урок. Функция printTriangle(height) извежда правоъгълен триъгълник от звездички с височина height. За 3:

Изход
*
* *
* * *
По-точно, за любопитните

В JavaScript / винаги дава дробно число, затова 5 / 9 е 0.5555…, а не 0, както в Java и C#. Ако ти трябва цялата част, пиши Math.trunc(a / b):

console.log(5 / 9);
console.log(Math.trunc(7 / 2));
Изход
0.5555555555555556
3

Упражнение

Функции за масиви

Всяка задача е една функция, която получава масив (или дума) и връща резултат. Накрая ги събери в една програма.

  1. sum, sumEven и sumOdd: сумата на всички, на четните и на нечетните числа в масива.
  2. reverse: връща нов масив с числата в обратен ред.
  3. max и min: най-голямото и най-малкото число.
  4. isPalindrome(word): дали думата се чете еднакво отпред назад и отзад напред.
  5. sumDiagonals и sumDiagonalsOnce: сумата по двата диагонала на квадратна матрица, с централния елемент два пъти и веднъж.
  6. Всичко заедно: за масива [1, 2, 3, 4, 5], числото 7 (с isPrime от горната карта), думите „капак“ и „АБВГД“ и матрицата 3 × 3 с числата от 1 до 9.
Изход от задача 6
Сума: 15, Четни: 6, Нечетни: 9
Обърнат: [5, 4, 3, 2, 1]
Макс: 5, Мин: 1
7 е просто: true
капак: true, АБВГД: false
Сума с повторение: 30, Сума без повторение: 25

Тест

Провери се

1. В function vat(price) { … } кое е параметърът?
2. Функцията дава нова стойност на своя параметър. Какво става с променливата, подадена при извикването?
3. Какво прави return?
4. Функцията стига до края си, без да мине през return. Какво връща?
5. Какво прави редът price = applyDiscount(price);?

Създаден от Иво Гергов като част от кампанията на Evo Tech за достъпно обучение по програмиране ·