Параметри и 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);Аргументите се свързват с параметрите по място: първият с item, вторият с qty. Променливата qty отвън няма нищо общо с параметъра qty, въпреки че се казват еднакво.
Проблем
Защо цената не се намали?
Написал си функция за 10% отстъпка и си я извикал:
function applyDiscount(price) { price = price * 0.9;}
const price = 100;applyDiscount(price);console.log(price); // 100100Цената пак е 100. Функцията не дава грешка, а отстъпката я няма. Къде отиде?
Виж го
Функцията получава копие
function applyDiscount(price) { price = price * 0.9;}
const price = 100;applyDiscount(price);console.log(price); // 100Стъпка по стъпка, с думи
- В програмата има променлива price = 100.
- Викаш applyDiscount(price): за функцията се заделя нова памет.
- Стойността се копира в нейния параметър price.
- Функцията намалява своето копие: 100 * 0.9 = 90.
- Функцията свършва и паметта ѝ изчезва, заедно с копието.
- А 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Стъпка по стъпка, с думи
- В програмата: price = 100.
- Викаш applyDiscount(price): заделя се памет за функцията.
- Стойността се копира в параметъра price.
- return price * 0.9: резултатът е 90.
- Резултатът се връща в програмата и се записва в price.
- Сега 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;
}return: без него функцията сметне price * 0.2 и изхвърли резултата, а извикването дава undefined.Пробвай
Върнато, но изгубено
Какво ще отпечата програмата?
function reserve(seats) { seats = seats - 2; console.log(`вътре: ${seats}`); return seats;}
const seats = 10;reserve(seats);console.log(`отвън: ${seats}`);Функцията променя копието си и връща 8, но никой не записва резултата. За да остане, трябва seats = reserve(seats);.
Тогава seats трябва да е обявена с let, защото стойността ѝ се сменя.
Идеята
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));04.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));0undefinedГрешка няма, затова такъв пропуск се хваща трудно. Гледай изхода и пробвай всеки път през функцията.
Пробвай
Намери грешката
Членовете на клуба имат 10% отстъпка, останалите плащат пълната цена. Но отстъпка получават всички. На кой ред е грешката?
Избери реда с грешката.
Последният return е за хората, които не са членове: те плащат пълната цена, return price;.
Упражнение
Функции, които смятат
Реши задачите в редактора си. Всяка функция получава каквото ѝ трябва като параметри и връща резултата. Печата се извън функциите, в редовете под тях.
1. Средно аритметично. Функция average(values) връща средното на числата в масива. Под нея прочети от клавиатурата колко са числата, после самите числа.
51015202530Средно аритметично: 202. Просто число. Функция isPrime(n) връща дали числото е просто (дели се само на 1 и на себе си). За 7 връща true, за 12 false.
3. Температури. Функции toFahrenheit(c) и toCelsius(f). F = C · 9 / 5 + 32. Прочети температура и мерна единица (C или F) и отпечатай превърнатата.
100C100 C = 212 F4. Калкулатор. Функция calculate(a, b, op) връща резултата за +, -, * или /. Операцията се избира с if.
105+10 + 5 = 155. Триъгълник с параметър. Обещахме го в миналия урок. Функция 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.55555555555555563Упражнение
Функции за масиви
Всяка задача е една функция, която получава масив (или дума) и връща резултат. Накрая ги събери в една програма.
sum,sumEvenиsumOdd: сумата на всички, на четните и на нечетните числа в масива.reverse: връща нов масив с числата в обратен ред.maxиmin: най-голямото и най-малкото число.isPalindrome(word): дали думата се чете еднакво отпред назад и отзад напред.sumDiagonalsиsumDiagonalsOnce: сумата по двата диагонала на квадратна матрица, с централния елемент два пъти и веднъж.- Всичко заедно: за масива
[1, 2, 3, 4, 5], числото 7 (сisPrimeот горната карта), думите „капак“ и „АБВГД“ и матрицата 3 × 3 с числата от 1 до 9.
Сума: 15, Четни: 6, Нечетни: 9Обърнат: [5, 4, 3, 2, 1]Макс: 5, Мин: 17 е просто: trueкапак: true, АБВГД: falseСума с повторение: 30, Сума без повторение: 25Тест