diff --git a/assets/chapter-10-images/06.Print-sign-02.png b/assets/chapter-10-images/06.Print-sign-02.png index eae4f0bf..0c630705 100644 Binary files a/assets/chapter-10-images/06.Print-sign-02.png and b/assets/chapter-10-images/06.Print-sign-02.png differ diff --git a/assets/chapter-10-images/15.Return-multiple-values-01.png b/assets/chapter-10-images/15.Return-multiple-values-01.png index 1e864b91..0d935c5e 100644 Binary files a/assets/chapter-10-images/15.Return-multiple-values-01.png and b/assets/chapter-10-images/15.Return-multiple-values-01.png differ diff --git a/chapter-10-functions.md b/chapter-10-functions.md index 0721bacb..f750903c 100644 --- a/chapter-10-functions.md +++ b/chapter-10-functions.md @@ -36,38 +36,38 @@ В езика JavaScript можем да **декларираме** функции буквално навсякъде, по същият начин, по който можем да декларираме и променливи навсякъде. Декларирането представлява **регистрирането на функцията** в програмата, за да бъде разпозната в останалата част от нея. -JavaScript не е **strongly typed** език (силно типизиран). Затова и когато **декларираме функция** тя няма тип (string, number, array и т.н.), какъвто имат методите и функциите в другите езици за програмиране. +JavaScript не е **силно типизиран** език (strongly typed). Затова и когато **декларираме функция** тя няма тип (string, number, array и т.н.), какъвто имат методите и функциите в другите езици за програмиране. Има 2 основни начина, по които могат да се декларирате функции в JavaScript - **декларативно - function declaration** и **експресивно - function expression**. ### Декларативно (function declaration) -Със следващия пример ще разгледаме задължителните елементи в декларацията на една функция **чрез function declaration**. +Със следващия пример ще разгледаме задължителните елементи в декларацията на една функция **декларативно (function declaration)**.  -* **Ключовата думичка function**. Започваме с използването на **ключовата думичка** ***function***, чрез която заявяваме, че предстои декларация на функция. Наричаме я ключова, защото тя е запазена в езика или с други думи казано - не можем да имаме променлива, която да именуваме по този начин. +* **Ключовата думичка function**. Започваме с използването на **ключовата думичка** ***function***, чрез която заявяваме, че предстои декларация на функция. Наричаме я ключова, защото тя е запазена в езика JavaScript или с други думи казано - не можем да имаме променлива, която да именуваме по този начин. * **Име на функцията**. Името на функцията е **определено от нас**, като не забравяме, че трябва да **описва задачата**, която се изпълнявана от кода в тялото на функцията. В примера името е **`getSquare`**, което ни указва, че задачата на тази функция е да изчисли лицето на квадрат. * **Списък с параметри**. Декларира се между скобите **`(`** и **`)`**, които изписваме след името му. Тук изброяваме поредицата от **параметри**, които функцията ще използва. Може да присъства **само един** параметър, **няколко** такива или да е **празен** списък. Ако няма параметри, то ще запишем само скобите **`()`**. В конкретния пример декларираме параметъра **`n`**. * **Тяло на функцията**. Декларира се между скобите **`{`** и **`}`**, които изписваме веднага след затварящата **`)`**. В **тялото на функцията** описваме **чрез код** всички операции, които искаме функцията да извърши. В тялото на функцията описваме **алгоритъма**, по който фунцкията решава даден проблем. Реализираме **логиката** на функцията. В показания пример изчисляваме лицето на квадрат, а именно **`n * n`**. При деклариране на функции е важно да спазваме **последователността** на основните елементи - първо **ключовата думичка function**, след това **име на функцията**, **списък от параметри**, ограден с кръгли скоби **`()`** и накрая **тяло на функцията**, оградено с фигурни скоби **`{}`**. -## Експресивно (function expression) +### Експресивно (function expression) -Със следващия пример ще разгледаме задължителните елементи в декларацията на една функция **чрез function expression**. То доста наподобява **декларативното**, което вече разгледахме и може да се каже, че е **комбинация** от **деклариране на променлива** и **деклариране на функция с function declaration**. +Със следващия пример ще разгледаме задължителните елементи в декларацията на една функция **експресивно (function expression)**. То доста наподобява **декларативното**, което вече разгледахме и може да се каже, че е **комбинация** от **деклариране на променлива** и **деклариране на функция декларативно (function declaration)**.  -* **Ключовата думичка let**. Започваме с използването на **ключовата думичка** **let**, чрез която заявяваме, че предстои декларация на променлива. +* **Ключовата думичка `let`**. Започваме с използването на **ключовата думичка** **`let`**, чрез която заявяваме, че предстои декларация на променлива. * **Име на променливата**. Името на променливата е **определено от нас**. В примера името е **`getSquare`**, което ни указва, че задачата на тази функция е да изчисли лицето на квадрат. * **Декларация на функция**. Използвайки същата структура, която вече научихме при **function declaration** - първо **ключовата думичка function**, след това **име на функцията**, **списък от параметри**, ограден с кръгли скоби **`()`** и накрая **тяло на функцията**, оградено с фигурни скоби **`{}`**. Особеното в случая е, че **името на функцията** не е задължителен елемент, но е препоръчително да свикнете да го добавяте. В примерът програмата ще работи без проблеми, дори и да пропуснем да изпишем името **`getSquareFunc`**. Ако пропуснем името, функцията се нарича **анонимна**. -Когато декларираме дадена променлива в тялото на една функция (чрез ключовата думичка **let** или **const**), я наричаме **локална** променлива за функцията. Областта, в която съществува и може да бъде използвана тази променлива, започва от реда, на който сме я декларирали и стига до затварящата къдрава скоба `}` на тялото на функцията. Тази област се нарича **област на видимост** на променливата (variable scope). +Когато декларираме дадена променлива в тялото на една функция (чрез ключовата думичка **`let`** или **`const`**), я наричаме **локална** променлива за функцията. Областта, в която съществува и може да бъде използвана тази променлива, започва от реда, на който сме я декларирали и стига до затварящата къдрава скоба `}` на тялото на функцията. Тази област се нарича **област на видимост** на променливата (variable scope). ### Декларативно или експресивно -Разликата между деклариране на функция чрез **деклараиия** или **експресия** е сравнително проста. Всички функции, декларирани чрез **function declaration**, се зареждат в паметта на програмата преди да започне нейното изпълнение, докато програмата разбира за функции, декларирани с **function expression** едва когато започне да се изпълнява и стигне до реда, на който е декларирана функцията. +Разликата между деклариране на функция чрез **декларация** или **експресия** е сравнително проста. Всички функции, декларирани чрез **function declaration**, се зареждат в паметта на програмата преди да започне нейното изпълнение, докато програмата разбира за функции, декларирани с **function expression** едва когато започне да се изпълнява и стигне до реда, на който е декларирана функцията. На практика това означава, че можете да **извикате функция**, декларирана с **function declaration** дори и в някои от предните редове - преди нейната декларация, докато ако опитате да направите това с **function expression** програмата ще ви **даде грешка**, че не разпознава тази функция по време на изпълнението. @@ -105,11 +105,11 @@ JavaScript не е **strongly typed** език (силно типизиран). #### Насоки и подсказки -Първата ни стъпка е да създадем функция за **принтиране на заглавната част** от касовата бележка (header). Нека му дадем смислено име, което описва кратко и ясно задачата му, например **`printReceiptHeader`**. В тялото му ще напишем кода от примера по-долу: +Първата ни стъпка е да създадем функция за **принтиране на заглавната част** от касовата бележка (header). Нека ѝ дадем смислено име, което описва кратко и ясно задачата ѝ, например **`printReceiptHeader`**. В тялото ѝ ще напишем следния код:  -Съвсем аналогично ще създадем още два функции **за разпечатване на средната част** на бележката (тяло) **`printReceiptBody`** и **за разпечатване на долната част** на бележката (footer) **`printReceiptFooter`**. +Съвсем аналогично ще създадем още две функции **за разпечатване на средната част** на бележката (тяло) **`printReceiptBody`** и **за разпечатване на долната част** на бележката (footer) **`printReceiptFooter`**. След това ще създадем и **още една функция**, която ще извиква трите функции, които написахме до момента една след друга: @@ -121,7 +121,7 @@ JavaScript не е **strongly typed** език (силно типизиран). #### Тестване в Judge системата -Програмата с общо четири функции, които се извикват една от друга, е готова и можем **да я изпълним и тестваме**, след което да я пратим за проверка в judge системата: [https://judge.softuni.bg/Contests/Practice/Index/943#0](https://judge.softuni.bg/Contests/Practice/Index/943#0). +Програмата с общо четири функции, които се извикват една от друга, е готова и можем **да я изпълним и тестваме**, след което да я пратим за проверка в Judge системата: [https://judge.softuni.bg/Contests/Practice/Index/943#0](https://judge.softuni.bg/Contests/Practice/Index/943#0). ## Функции с параметри @@ -129,11 +129,9 @@ JavaScript не е **strongly typed** език (силно типизиран). ### Използване на параметри във функции -Ако функцията ни изисква **входни данни**, то те се подават в скобите **`()`**, като последователността на **фактическите параметри** трябва да съвпада с последователността на подадените при декларирането на функцията. +Ако функцията ни изисква **входни данни**, то те се подават в скобите **`()`**, като последователността на **фактическите параметри** трябва да съвпада с последователността на подадените при декларирането на функцията. Както отбелязахме по-горе, **параметрите освен нула на брой, могат също така да са един или няколко**. При декларацията им ги разделяме със запетая. -Както отбелязахме по-горе, **параметрите освен нула на брой, могат също така да са един или няколко**. При декларацията им ги разделяме със запетая. - -**Декларираме** функцията `printNumbers` и **списъка** с **параметри**, от които тя се нуждае, за да работи коректно, след което пишем кода, който ще изпълнява. +**Декларираме** функцията **`printNumbers(...)`** и **списъка** с **параметри**, от които тя се нуждае, за да работи коректно, след което пишем кода, който ще изпълнява:  @@ -141,7 +139,7 @@ JavaScript не е **strongly typed** език (силно типизиран).  -При **декларирането на параметри** трябва да внимаване всеки един параметър да има **име**. Важно е при извикване на функцията, да подаваме **стойности** за параметрите по **реда**, в който са **декларирани** самите те. В примера, който разгледахме на променливата `start` ще бъде присвоена стойността на първият подаден параметър - в нашият случай числото 5. На променливата `end` ще бъде присвоена стойността на вторият параметър, който сме подали - в случая числото 10. +При **декларирането на параметри** трябва да внимаване всеки един параметър да има **име**. Важно е при извикване на функцията, да подаваме **стойности** за параметрите по **реда**, в който са **декларирани** самите те. В примера, който разгледахме на променливата **`start`** ще бъде присвоена стойността на първият подаден параметър - в нашият случай числото 5. На променливата **`end`** ще бъде присвоена стойността на вторият параметър, който сме подали - в случая числото 10. Важно е да се отбележи, че в езикът **JavaScript** декларирането на функция с даден **брой параметри**, не ни задължава да извикваме функцията със **същият брой параметри**. Можем да извикаме функция като и подадем както **повече**, така и **по - малко** параметри, като това няма да доведе до грешка. @@ -149,13 +147,13 @@ JavaScript не е **strongly typed** език (силно типизиран).  -В случая извикваме функцията **`printNumbers`** като и подаваме 4, вместо **декларираните** 2 параметъра. Всички излишни параметри ще бъдат **игнорирани**. Т.е. числата 15 и 20, няма да стигнат до функцията, защото нямаме **деклариран параметър**, който да ги приеме. +В случая извикваме функцията **`printNumbers(...)`** като и подаваме 4, вместо **декларираните** 2 параметъра. Всички излишни параметри ще бъдат **игнорирани**. Т.е. числата 15 и 20, няма да стигнат до функцията, защото нямаме **деклариран параметър**, който да ги приеме. Нека разгледаме още един пример:  -В случая извикваме функцията **`printNumbers`** като и подаваме 1, вместо **декларираните** 2 параметъра. Всички параметри, за които **не е подадена стойност**, ще получат автоматично стойност **`undefined`**. В нашият случай променливата **`secondNumber`** ще има стойност **`undefined`**. +В случая извикваме функцията **`printNumbers(...)`** като и подаваме 1, вместо **декларираните** 2 параметъра. Всички параметри, за които **не е подадена стойност**, ще получат автоматично стойност **`undefined`**. В нашият случай променливата **`secondNumber`** ще има стойност **`undefined`**. ### Пример: знак на цяло число @@ -171,13 +169,13 @@ JavaScript не е **strongly typed** език (силно типизиран). #### Насоки и подсказки -Първата ни стъпка е **декларирането** на функция и даването ѝ на описателно име, например **`printSign`**. Тази функция ще има само един параметър. +Първата ни стъпка е **декларирането** на функция и даването ѝ на описателно име, например **`printSign`**. Тази функция ще има само един параметър:  Следващата ни стъпка е **имплементирането** на логиката, по която програмата ни ще проверява какъв точно е знакът на числото. От примерите виждаме, че има три случая - числото е по-голямо от нула, равно на нула или по-малко от нула, което означава, че ще направим три проверки в тялото на функцията. -Следващата ни стъпка е да извикаме функцията, която създадохме. +Следващата ни стъпка е да извикаме функцията, която създадохме:  @@ -188,13 +186,13 @@ JavaScript не е **strongly typed** език (силно типизиран). ### Незадължителни параметри -Езикът JavaScript поддържа използването на **незадължителни** параметри. Те позволяват **пропускането** на параметри при извикването на функцията. Декларирането им става чрез **осигуряване на стойност по подразбиране** в описанието на съответния параметър. +Езикът **JavaScript** поддържа използването на **незадължителни** параметри. Те позволяват **пропускането** на параметри при извикването на функцията. Декларирането им става чрез **осигуряване на стойност по подразбиране** в описанието на съответния параметър. Следващият пример онагледява употребата на незадължителните параметри:  -Показаната функция **`printNumbers`** може да бъде извикана по няколко начина: +Показаната функция **`printNumbers(...)`** може да бъде извикана по няколко начина:  @@ -212,7 +210,7 @@ JavaScript не е **strongly typed** език (силно типизиран). #### Насоки и подсказки -Избираме смислено име за функцията, което описва целта ѝ, например **`printLine`**, и го имплементираме. +Избираме смислено име за функцията, което описва целта ѝ, например **`printLine`**, и я имплементираме:  @@ -247,11 +245,11 @@ JavaScript не е **strongly typed** език (силно типизиран). #### Насоки и подсказки -Създаваме функция, която ще принтира първия и последен ред, тъй като те са еднакви. Нека не забравяме, че трябва да му дадем **описателно име** и да му зададем като **параметър** дължината на страната. Ще използваме вградената функция **`repeat`**. +Създаваме функция, която ще принтира първия и последен ред, тъй като те са еднакви. Нека не забравяме, че трябва да му дадем **описателно име** и да му зададем като **параметър** дължината на страната. Ще използваме вградения метод **`repeat(...)`**:  -Следващата ни стъпка е да създадем функция, която ще рисува на конзолата средните редове. Отново задаваме описателно име, например **`printMiddleRow`**. +Следващата ни стъпка е да създадем функция, която ще рисува на конзолата средните редове. Отново задаваме описателно име, например **`printMiddleRow`**:  @@ -284,17 +282,12 @@ JavaScript не е **strongly typed** език (силно типизиран). #### Кодът след return е недостъпен -В случай, че **return** операторът не се намира в условна конструкция като `if`, след него, в текущия блок, **не** трябва да има други редове код, тъй като тогава Visual Studio Code ще покаже предупреждение, съобщавайки ни, че е засякъл код, който **не може да бъде достъпен**: +В случай, че **return** операторът не се намира в условна конструкция като **`if`**, след него, в текущия блок, **не** трябва да има други редове код, тъй като тогава Visual Studio Code ще покаже предупреждение, съобщавайки ни, че е засякъл код, който **не може да бъде достъпен**:  Операторът **`return`** може да бъде използван и без да бъде специфицирана **конкретна стойност**, която да бъде върната. В този случай, просто ще бъде **прекратено** изпълнението на кода във функцията и ще бъде върната стойност по подразбиране **`undefined`**. ------ - -В посоченият пример... - -
![]() | В програмирането не може да има два пъти оператор return един след друг, защото изпълнението на първия няма да позволи да се изпълни вторият. Понякога програмистите се шегуват с фразата “пиши return; return; и да си ходим”, за да обяснят, че логиката на програмата е объркана. |