Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,45 +1,91 @@
Функции позволяют избежать повторения кода. Если одни и те же действия нужны в разных местах программы, их выносят в функцию.
До этого момента мы использовали только готовые функции: `console.log()`, `Math.pow()` и другие. Но в JavaScript можно создавать свои собственные функции, и пришла пора научиться это делать.

## Объявление функции
## Зачем определять функции

Допустим, у нас есть несколько похожих участков кода:

```javascript
console.log('Hello, Hexlet!');
console.log('Hello, world!');
console.log('Hello, JavaScript!');
```

Чтобы не повторять один и тот же шаблон, его можно оформить в виде своей функции, которая принимает параметр и печатает нужную строку:

```javascript
function sayHello() {
console.log('Hello!');
function sayHello(name) {
console.log(`Hello, ${name}!`);
}
```

Теперь её можно вызывать с разными аргументами:

// Вызов функции
sayHello(); // => Hello!
sayHello(); // => Hello! (можно вызвать сколько угодно раз)
```javascript
sayHello('Hexlet'); // => Hello, Hexlet!
sayHello('world'); // => Hello, world!
sayHello('JavaScript'); // => Hello, JavaScript!
```

Ключевое слово `function`, затем имя функции, скобки и тело в фигурных скобках.
Кода вроде бы не стало меньше, но появилось другое преимущество: если функция используется в разных местах, то для изменения текста достаточно поправить только её определение. Чем сложнее задача и чем чаще она встречается, тем важнее выделять логику в отдельные функции.

## Функции с параметрами
## Синтаксис определения

```javascript
function greet(name) {
console.log(`Hello, ${name}!`);
function имяФункции(параметры) {
тело
}
```

greet('Alice'); // => Hello, Alice!
greet('Bob'); // => Hello, Bob!
```text
function greet(name) { ← ключевое слово, имя и параметр
return 'Hello, ' + name; ← тело функции
}
```

Определение начинается с ключевого слова `function`, затем идёт имя функции (по тем же правилам, что и у переменных), в скобках — список параметров через запятую, а тело функции заключается в фигурные скобки `{}`.

## Определить функцию — не значит вызвать её

Определение функции не запускает её код. Тело выполнится только при вызове. Посмотрите на пример:

```javascript
function sayHi() {
console.log('Hi!');
}

console.log('Программа продолжается…');
```

Параметр `name` — это переменная, доступная внутри функции. При каждом вызове в неё подставляется переданный аргумент.
Здесь функция `sayHi()` определена, но её тело не выполняется — на экран попадёт только `Программа продолжается…`. Чтобы `sayHi()` сработала, её нужно явно вызвать:

## Несколько параметров
```javascript
function sayHi() {
console.log('Hi!');
}

sayHi(); // => Hi!
console.log('Программа продолжается…');
```

## Пример: функция для печати среднего арифметического

Реализуем функцию, которая **вычисляет и печатает среднее арифметическое** двух чисел. Среднее арифметическое — это сумма чисел, делённая на их количество. Например, среднее от 6 и 4: `(6 + 4) / 2 = 5`.

```javascript
function add(a, b) {
console.log(a + b);
function printAverage(a, b) {
const total = a + b;
const average = total / 2;
console.log(average);
}

add(3, 4); // => 7
printAverage(6, 4); // => 5
```

Здесь `a` и `b` — входные параметры, `total` содержит их сумму, `average` получается делением суммы на 2, а `console.log()` выводит результат.

## Стрелочные функции

В JavaScript есть сокращённая запись через стрелку `=>`:
В JavaScript есть и сокращённая запись через стрелку `=>`:

```javascript
const greet = (name) => {
Expand All @@ -49,4 +95,8 @@ const greet = (name) => {
greet('Alice'); // => Hello, Alice!
```

Обе формы равнозначны, но стрелочная функция записывается в переменную.
Обе формы равнозначны; стрелочную функцию записывают в переменную. Подробнее этот синтаксис мы разберём в отдельном уроке.

## Переиспользование и читаемость

Функции помогают избегать дублирования и делают программы понятнее. Само название функции говорит, что она делает. Это особенно важно в больших проектах, где код читают другие программисты (или вы сами через месяц).
Original file line number Diff line number Diff line change
@@ -1,16 +1,29 @@
Функция может не только выполнять действия, но и **возвращать результат** с помощью оператора `return`.
В этом уроке мы научимся писать функции, которые **возвращают значения**. Такие функции отдают результат своей работы, как будто говорят: «Вот, держи, я посчитала».

Например, функция может вернуть строку с обработанным текстом или число, вычисленное по формуле. Возвращённое значение можно использовать дальше: сохранить в переменную, передать в другую функцию или вывести на экран.

Чтобы функция отдала результат, используется специальное ключевое слово `return`. Оно завершает выполнение функции и указывает, что именно нужно вернуть.

Вот функция, которая делает текст заглавным:

```javascript
function add(a, b) {
return a + b;
function shout(name) {
return name.toUpperCase();
}

const result = add(3, 4);
console.log(result); // => 7
const result = shout('hexlet');
console.log(result); // => HEXLET

const result2 = shout('code-basics');
console.log(result2); // => CODE-BASICS
```

При вызове `shout('hexlet')` сначала выполняется выражение `name.toUpperCase()`, оно возвращает строку `'HEXLET'`. Затем `return` отдаёт это значение наружу — туда, откуда была вызвана функция. В нашем случае оно сохраняется в переменную `result`, а потом выводится на экран.

## Разница между return и console.log

В отличие от `console.log()`, `return` ничего не печатает. Он просто возвращает значение, а решение о том, что с ним делать, принимает вызывающий код.

```javascript
// Эта функция выводит, но ничего не возвращает
function printSum(a, b) {
Expand All @@ -22,23 +35,51 @@ function getSum(a, b) {
return a + b;
}

// Вернувший результат можно использовать дальше
// Возвращённый результат можно использовать дальше
const sum = getSum(3, 4);
console.log(sum * 2); // => 14
```

## return завершает функцию
## Возврат вычисленного выражения

После `return` функция немедленно завершается. Код после `return` не выполняется.
В `return` обычно указывают **выражение**, которое сначала вычисляется, а потом результат передаётся наружу:

```javascript
function getSign(n) {
if (n > 0) return 'positive';
if (n < 0) return 'negative';
return 'zero';
function fullName(first, last) {
return `${first} ${last}`;
}

console.log(getSign(5)); // => positive
console.log(getSign(-3)); // => negative
console.log(getSign(0)); // => zero
const name = fullName('Aria', 'Stark');
console.log(name); // => Aria Stark
```

Сначала вычисляется шаблонная строка, и уже готовое значение возвращается наружу.

## Многострочные функции

Иногда в теле функции нужно сделать несколько шагов, прежде чем получить результат. Тогда пишут несколько строк, а в конце используют `return`. Например, функция форматирует имя: убирает пробелы по краям и переводит буквы в верхний регистр.

```javascript
function formatName(name) {
const clean = name.trim();
const uppercased = clean.toUpperCase();
return uppercased;
}

console.log(formatName(' hexlet ')); // => HEXLET
```

## Код после return

Когда выполнение доходит до `return`, функция немедленно завершается. Всё, что написано после него внутри функции, **не выполнится**:

```javascript
function example() {
return 'готово';
console.log('этот код никогда не выполнится');
}

console.log(example()); // => готово
```

Поэтому `return` обычно пишут в конце логики. Позже, когда мы дойдём до условных конструкций, вы увидите, что таких «концов» внутри одной функции может быть несколько.
Original file line number Diff line number Diff line change
@@ -1,37 +1,75 @@
Параметры функции могут иметь **значения по умолчанию**. Если аргумент не передан — используется значение по умолчанию.
Функции могут принимать параметры. Иногда удобно задать значение сразу в определении функции, чтобы не указывать его при каждом вызове. Такое значение называется **значением по умолчанию**.

Если аргумент не передан, используется это значение. Если аргумент указан, он заменяет умолчание.

```javascript
function greet(name = 'World') {
console.log(`Hello, ${name}!`);
}

greet('Alice'); // => Hello, Alice!
greet(); // => Hello, World! (использован default)
greet(); // => Hello, World! (использовано значение по умолчанию)
```

## Пример: скрытие номера карты
## Пример: повторение текста

Сделаем функцию, которая повторяет строку несколько раз. По умолчанию пусть будет один раз, но при желании можно указать другое количество. Для повторения строки в JavaScript есть метод `repeat()`:

```javascript
function getHiddenCard(cardNumber, starsCount = 4) {
return '*'.repeat(starsCount) + cardNumber.slice(-4);
function repeat(text, times = 1) {
return text.repeat(times);
}

console.log(getHiddenCard('1234567890123456')); // => ****3456
console.log(getHiddenCard('1234567890123456', 2)); // => **3456
console.log(repeat('Hi')); // => Hi
console.log(repeat('Hi', 3)); // => HiHiHi
```

Параметр `starsCount` по умолчанию равен `4`, но можно передать другое значение.
```text
function repeat(text, times = 1) ← times имеет значение по умолчанию

Check notice on line 28 in modules/40-define-functions/340-define-functions-default-parameters/ru/README.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] modules/40-define-functions/340-define-functions-default-parameters/ru/README.md#L28

Unpaired symbol: ‘'’ seems to be missing (EN_UNPAIRED_QUOTES) URL: https://languagetool.org/insights/post/punctuation-guide/#what-are-parentheses Rule: https://community.languagetool.org/rule/show/EN_UNPAIRED_QUOTES?lang=en-US Category: PUNCTUATION
Raw output
modules/40-define-functions/340-define-functions-default-parameters/ru/README.md:28:80: Unpaired symbol: ‘'’ seems to be missing (EN_UNPAIRED_QUOTES)
 URL: https://languagetool.org/insights/post/punctuation-guide/#what-are-parentheses 
 Rule: https://community.languagetool.org/rule/show/EN_UNPAIRED_QUOTES?lang=en-US
 Category: PUNCTUATION

## Несколько параметров по умолчанию
repeat('go') → times = 1 (по умолчанию)
repeat('go', 5) → times = 5 (явно указано)
```

Необязательные параметры всегда указываются **в конце** списка. Поэтому сначала идёт обязательный параметр `text`, а уже после него — `times` со значением по умолчанию.

Параметры с defaults должны идти **после** обязательных параметров.
## Пример: склейка слов с разделителем

По умолчанию слова соединяются пробелом, но можно указать другой символ:

```javascript
function repeat(str, times = 2, separator = ' ') {
return Array(times).fill(str).join(separator);
function joinWords(word1, word2, separator = ' ') {
return word1 + separator + word2;
}

console.log(repeat('ha')); // => ha ha
console.log(repeat('ha', 3)); // => ha ha ha
console.log(repeat('ha', 3, '-')); // => ha-ha-ha
console.log(joinWords('King', 'Road')); // => King Road
console.log(joinWords('Dragon', 'stone', '-')); // => Dragon-stone
```

## Пример: несколько параметров по умолчанию

Функция может содержать более одного параметра со значением по умолчанию. Сделаем функцию, которая строит строку-разделитель. По умолчанию символ — дефис, а длина равна 10:

```javascript
function makeLine(symbol = '-', length = 10) {
return symbol.repeat(length);
}

console.log(makeLine()); // => ----------
console.log(makeLine('*')); // => **********
console.log(makeLine('*', 5)); // => *****
console.log(makeLine('#', 3)); // => ###
```

## Пример: скрытие номера карты

```javascript
function getHiddenCard(cardNumber, starsCount = 4) {
return '*'.repeat(starsCount) + cardNumber.slice(-4);
}

console.log(getHiddenCard('1234567890123456')); // => ****3456
console.log(getHiddenCard('1234567890123456', 2)); // => **3456
```

Параметр `starsCount` по умолчанию равен `4`, но можно передать другое значение.
Loading