|
|
|
@ -0,0 +1,197 @@
|
|
|
|
|
# Основы JavaScript: методы и функции
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
> Скетчноут [Tomomi Imura](https://twitter.com/girlie_mac)
|
|
|
|
|
|
|
|
|
|
## Предлекционный квиз
|
|
|
|
|
|
|
|
|
|
[Предлекционный квиз](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/9)
|
|
|
|
|
|
|
|
|
|
Когда мы думаем о написании кода, мы всегда хотим убедиться, что наш код читаем. Хотя это звучит нелогично, код читается гораздо чаще, чем пишется. Одним из основных инструментов разработчика для обеспечения поддерживаемого кода является **функция**.
|
|
|
|
|
|
|
|
|
|
[](https://youtube.com/watch?v=XgKsD6Zwvlc "Methods and Functions")
|
|
|
|
|
|
|
|
|
|
> 🎥 Нажмите на изображения выше, чтобы посмотреть видео о методах и функциях.
|
|
|
|
|
> Вы можете пройти этот урок на [Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101-functions/?WT.mc_id=academic-13441-cxa)!
|
|
|
|
|
|
|
|
|
|
## Функции
|
|
|
|
|
|
|
|
|
|
По своей сути функция — это блок кода, который мы можем выполнить при неоходимости. Это идеально подходит для сценариев, когда нам нужно выполнять одну и ту же задачу несколько раз; вместо того, чтобы дублировать логику в нескольких местах (что затруднит внесение изменений, когда они понадобятся), мы можем централизовать ее в одном месте (одной функции) и вызывать ее всякий раз, когда нам нужно ее выполнить. Также можно вызывать функции из других функций!
|
|
|
|
|
|
|
|
|
|
Столь же важна возможность давать функции название. Хотя это может показаться тривиальным, имя функции обеспечивает быстрый способ документирования раздела кода. Вы можете думать об этом как о метке на кнопке. Если я нажму кнопку с надписью «Отменить таймер», я знаю, что часы остановятся.
|
|
|
|
|
|
|
|
|
|
## Создание и вызов функции
|
|
|
|
|
|
|
|
|
|
Синтаксис функции выглядит следующим образом:
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
function nameOfFunction() {
|
|
|
|
|
// объявление функции
|
|
|
|
|
// определение/тело функции
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Если бы мы захотели создать функцию для приветствия, это могло бы выглядеть так:
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
function displayGreeting() {
|
|
|
|
|
console.log("Hello, world!");
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Всякий раз, когда мы хотим вызвать нашу функцию, мы используем имя функции, за которым следует `()`. Стоит отметить тот факт, что наша функция может быть определена до или после того, как мы решим ее вызвать; компилятор JavaScript найдет её за вас.
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
// вызов нашей функции
|
|
|
|
|
displayGreeting();
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
> **ПРИМЕЧАНИЕ.** Существует специальный тип функции, известный как **метод**, который вы уже использовали! На самом деле, мы видели это в нашей демонстрации выше, когда использовали `console.log`. Что отличает метод от функции, так это то, что метод привязан к объекту (`console` в нашем примере), в то время как функция является свободно плавающей. Вы услышите, как многие разработчики используют эти термины как синонимы.
|
|
|
|
|
|
|
|
|
|
### Лучшие практики написания функций
|
|
|
|
|
|
|
|
|
|
Существует несколько рекомендаций, которые следует учитывать при создании функций.
|
|
|
|
|
|
|
|
|
|
- Используйте говорящие имена, чтобы вы знали, что будет делать функция.
|
|
|
|
|
- Используйте **верблюжью нотацию** для объединения слов.
|
|
|
|
|
- Сосредоточьте свои функции на конкретной задаче
|
|
|
|
|
|
|
|
|
|
## Передача информации в функцию
|
|
|
|
|
|
|
|
|
|
Чтобы сделать функцию более пригодной для повторного использования, вам часто нужно передавать в нее информацию. Если мы рассмотрим наш пример `displayGreeting` выше, он будет отображать только **Hello, world!**. Не самая полезная функция, которую можно было бы создать. Если мы хотим сделать ее немного более гибкой, например, разрешить кому-то указать имя человека, которого нужно приветствовать, мы можем добавить **параметр**. Параметр (также иногда называемый **аргументом**) — это дополнительная информация, отправляемая функции.
|
|
|
|
|
|
|
|
|
|
Параметры перечисляются при объявлении функции в круглых скобках и разделены запятыми следующим образом:
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
function name(param, param2, param3) {}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Мы можем обновить функцию `displayGreeting`, чтобы она принимала имя и вывела его.
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
function displayGreeting(name) {
|
|
|
|
|
const message = `Hello, ${name}!`;
|
|
|
|
|
console.log(message);
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Когда мы хотим вызвать нашу функцию и передать параметр, мы указываем его в скобках.
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
displayGreeting("Christopher");
|
|
|
|
|
// выводит "Hello, Christopher" при запуске
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Значения по умолчанию
|
|
|
|
|
|
|
|
|
|
Мы можем сделать нашу функцию еще более гибкой, добавив больше параметров. Но что, если мы не хотим указывать каждое значение? Продолжая наш пример с приветствием, мы могли бы оставить имя как ранее (нам нужно знать, кого мы приветствуем), но мы хотели бы, чтобы само приветствие можно было настроить по желанию. Если кто-то не хочет настраивать его, вместо этого мы предоставляем значение по умолчанию. Значение по умолчанию параметру мы устанавливаем так же, как мы устанавливаем значение для переменной — `имяПараметра = 'значениеПоУмолчанию'`. Далее следует пример:
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
function displayGreeting(name, salutation = "Hello") {
|
|
|
|
|
console.log(`${salutation}, ${name}`);
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Когда мы вызываем функцию, мы можем решить, хотим ли мы установить значение для `salutation(приветствия)`.
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
displayGreeting("Christopher");
|
|
|
|
|
// выводит "Hello, Christopher"
|
|
|
|
|
|
|
|
|
|
displayGreeting("Christopher", "Hi");
|
|
|
|
|
// выводит "Hi, Christopher"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Возвращаемые значения
|
|
|
|
|
|
|
|
|
|
До сих пор созданная нами функция всегда выводила данные в [консоль](https://developer.mozilla.org/docs/Web/API/console). Иногда это может быть именно то, что нам нужно, особенно когда мы создаем функции, которые будут вызывать другие сервисы. Но что, если мы хотим создать вспомогательную функцию для выполнения вычислений и вернуть значение, чтобы можно было его использовать в другом месте?
|
|
|
|
|
|
|
|
|
|
Мы можем сделать это, используя **возвращаемое значение (return value)**. Значение возвращается функцией и может быть сохранено в переменной точно так же, как если бы мы сохраняли буквальное значение, такое как строка или число.
|
|
|
|
|
|
|
|
|
|
Если функция что-то возвращает, используется ключевое слово `return`. Ключевое слово `return` ожидает значение или ссылку на то, что возвращается, например:
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
return myVariable;
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Мы могли бы создать вспомогательную функцию для создания приветственного сообщения и возврата этого сообщения вызывающей функции.
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
function createGreetingMessage(name) {
|
|
|
|
|
const message = `Hello, ${name}`;
|
|
|
|
|
return message;
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
При вызове этой функции мы сохраним значение в переменной. Это во многом похоже на то, как мы присваиваем переменной статическое значение (например, `const name = 'Christopher'`).
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
const greetingMessage = createGreetingMessage("Christopher");
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Функции как параметры для функций
|
|
|
|
|
|
|
|
|
|
По мере продвижения по карьере программиста вы будете сталкиваться с функциями, которые принимают функции в качестве параметров. Этот изящный трюк обычно используется тогда, когда мы не знаем, когда что-то произойдет или завершится, но знаем, что нам нужно выполнить операцию в ответ.
|
|
|
|
|
|
|
|
|
|
В качестве примера рассмотрим [setTimeout](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout), который запускает таймер и выполняет код по завершении. Нам нужно сообщить ему, какой код мы хотим выполнить. Звучит как идеальная работа для функции!
|
|
|
|
|
|
|
|
|
|
Если вы запустите приведенный ниже код, через 3 секунды вы увидите сообщение **Прошло 3 секунды**.
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
function displayDone() {
|
|
|
|
|
console.log("Прошло 3 секунды");
|
|
|
|
|
}
|
|
|
|
|
// время таймера в миллисекундах
|
|
|
|
|
setTimeout(displayDone, 3000);
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Анонимные функции
|
|
|
|
|
|
|
|
|
|
Давайте еще раз посмотрим на то, что мы написали. Мы создали функцию с именем, которая будет вызвана только один раз. По мере того, как наше приложение будет становиться все более сложным, мы увидим, что создаем множество функций, которые будут вызваны только один раз. Не самое лучшее решение. Как оказалось, нам не всегда нужно указывать имя для функции!
|
|
|
|
|
|
|
|
|
|
Когда мы передаем функцию в качестве параметра, мы можем не создавать ее заранее и вместо этого создавать ее как часть параметра. Мы используем то же ключевое слово `function`, но вместо этого мы передаем ее как параметр.
|
|
|
|
|
|
|
|
|
|
Давайте перепишем код выше, чтобы использовать анонимную функцию:
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
setTimeout(function () {
|
|
|
|
|
console.log("Прошло 3 секунды");
|
|
|
|
|
}, 3000);
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Если вы запустите наш новый код, вы заметите, что мы получаем тот же результат. Мы создали функцию, но мы не дали ей название!
|
|
|
|
|
|
|
|
|
|
### Стрелочная функция
|
|
|
|
|
|
|
|
|
|
Одно из сокращений, распространенное во многих языках программирования (включая JavaScript), — это возможность использовать так называемую **стрелочную функцию**. Она использует специальный индикатор `=>`, который выглядит как стрелка - отсюда и название! Используя `=>`, мы можем пропустить ключевое слово `function`.
|
|
|
|
|
|
|
|
|
|
Давайте перепишем наш код еще раз, но теперь с использованием стрелочной функции:
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
console.log("Прошло 3 секунды");
|
|
|
|
|
}, 3000);
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Когда использовать каждую стратегию
|
|
|
|
|
|
|
|
|
|
Вы уже видели, что существует три способа передачи функции в качестве параметра, и вам может быть интересно, когда использовать каждый из них. Если вы знаете, что будете использовать эту функцию более одного раза, создайте ее как обычно. Если вы будете использовать ее только один раз, используйте анонимную функцию. Не имеет значения, используете ли вы стрелочную функцию, или более традиционный синтаксис с ключевым словом `function`, так как они взаимозаменяемы. Какой из способов написания функции выбрать, решать вам, но вы заметите, что большинство современных разработчиков предпочитают `=>`.
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 🚀 Челлендж
|
|
|
|
|
|
|
|
|
|
Можете ли вы сформулировать в одном предложении разницу между функциями и методами? Попробуйте!
|
|
|
|
|
|
|
|
|
|
## Постлекционный квиз
|
|
|
|
|
|
|
|
|
|
[Постлекционный квиз](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/10)
|
|
|
|
|
|
|
|
|
|
## Обзор и самообучение
|
|
|
|
|
|
|
|
|
|
Стоит [почитать немного больше о стрелочных функциях](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions), поскольку они все чаще используются при написании кода. Попрактикуйтесь в написании функции, а затем перепишите ее с помощью этого синтаксиса.
|
|
|
|
|
|
|
|
|
|
## Задание
|
|
|
|
|
|
|
|
|
|
[Веселье с функциями](assignment.ru.md)
|