JavaScript: Создание (определение) функций
До этого момента мы использовали только готовые функции: console.log(), Math.pow() и другие. Но в JavaScript можно создавать свои собственные функции, и пришла пора научиться это делать.
Зачем определять функции
Допустим, у нас есть несколько похожих участков кода:
console.log("Hello, Hexlet!");
console.log("Hello, world!");
console.log("Hello, JavaScript!");Чтобы не повторять один и тот же шаблон, его можно оформить в виде своей функции, которая принимает параметр и печатает нужную строку:
function sayHello(name) {
console.log(`Hello, ${name}!`);
}Теперь её можно вызывать с разными аргументами:
sayHello("Hexlet"); // => Hello, Hexlet!
sayHello("world"); // => Hello, world!
sayHello("JavaScript"); // => Hello, JavaScript!Кода вроде бы не стало меньше, но появилось другое преимущество: если функция используется в разных местах, то для изменения текста достаточно поправить только её определение. Чем сложнее задача и чем чаще она встречается, тем важнее выделять логику в отдельные функции.
Синтаксис определения
function имяФункции(параметры) {
тело;
}function greet(name) { ← ключевое слово, имя и параметр
return 'Hello, ' + name; ← тело функции
}Определение начинается с ключевого слова function, затем идёт имя функции (по тем же правилам, что и у переменных), в скобках — список параметров через запятую, а тело функции заключается в фигурные скобки {}.
Определить функцию — не значит вызвать её
Определение функции не запускает её код. Тело выполнится только при вызове. Посмотрите на пример:
function sayHi() {
console.log("Hi!");
}
console.log("Программа продолжается…");Здесь функция sayHi() определена, но её тело не выполняется — на экран попадёт только Программа продолжается…. Чтобы sayHi() сработала, её нужно явно вызвать:
function sayHi() {
console.log("Hi!");
}
sayHi(); // => Hi!
console.log("Программа продолжается…");Пример: функция для печати среднего арифметического
Реализуем функцию, которая вычисляет и печатает среднее арифметическое двух чисел. Среднее арифметическое — это сумма чисел, делённая на их количество. Например, среднее от 6 и 4: (6 + 4) / 2 = 5.
function printAverage(a, b) {
const total = a + b;
const average = total / 2;
console.log(average);
}
printAverage(6, 4); // => 5Здесь a и b — входные параметры, total содержит их сумму, average получается делением суммы на 2, а console.log() выводит результат.
Имена и порядок параметров
Имя параметра может быть любым — главное, чтобы оно отражало смысл значения, которое попадёт внутрь. С внешним кодом оно никак не связано:
function getLastChar(str) {
return str[str.length - 1];
}
// Внутри функции str будет равна 'Winter is coming'.
// Имя переменной снаружи не связано с именем параметра
const text = "Winter is coming";
console.log(getLastChar(text)); // => gКогда параметров два и больше, для большинства функций становится важен порядок их передачи. Если его поменять, функция отработает по-другому:
// Первый параметр — что ищем, второй — на что меняем
console.log("google".replace("go", "mo")); // => moogle
// Ничего не заменилось: внутри 'google' нет 'mo'
console.log("google".replace("mo", "go")); // => googleДругие формы записи
Функцию можно не только объявить через function, но и записать как значение и присвоить константе:
const sayHello = function (name) {
console.log(`Hello, ${name}!`);
};
sayHello("Hexlet"); // => Hello, Hexlet!Такую запись называют функциональным выражением. Обратите внимание на точку с запятой в конце: перед нами обычное присваивание константы, а не объявление функции.
У функционального выражения есть короткая форма, стрелочная. Слово function в ней заменяется на стрелку =>, которая ставится после списка параметров:
const sayHello = (name) => {
console.log(`Hello, ${name}!`);
};
sayHello("Hexlet"); // => Hello, Hexlet!Для наших задач все три записи равнозначны: функцию определяют, а потом вызывают по имени. Стрелочная форма в JavaScript встречается чаще остальных, поэтому дальше в курсе примеры записаны именно так. Отдельный урок этого модуля покажет, как сократить её ещё сильнее.
Переиспользование и читаемость
Функции помогают избегать дублирования и делают программы понятнее. Само название функции говорит, что она делает. Это особенно важно в больших проектах, где код читают другие программисты (или вы сами через месяц).
Задание
Сайт выводит приветствие для каждого посетителя. Реализуйте функцию sayHello(), которая выводит на экран фразу Hello, World!.
sayHello(); // => Hello, World!В задачах, где нужно реализовать функцию, вызывать её самим не нужно — это сделают автоматические тесты. Пример вызова показан лишь для того, чтобы вы понимали, как функция будет использоваться.
Примечание: в файле уже есть строка
export default …— она служебная, нужна системе проверки; что такое экспорт, разберём в уроке про модули.
Полезное
JavaScript: Создание (определение) функций
До этого момента мы использовали только готовые функции: console.log(), Math.pow() и другие. Но в JavaScript можно создавать свои собственные функции, и пришла пора научиться это делать.
Зачем определять функции
Допустим, у нас есть несколько похожих участков кода:
console.log("Hello, Hexlet!");
console.log("Hello, world!");
console.log("Hello, JavaScript!");Чтобы не повторять один и тот же шаблон, его можно оформить в виде своей функции, которая принимает параметр и печатает нужную строку:
function sayHello(name) {
console.log(`Hello, ${name}!`);
}Теперь её можно вызывать с разными аргументами:
sayHello("Hexlet"); // => Hello, Hexlet!
sayHello("world"); // => Hello, world!
sayHello("JavaScript"); // => Hello, JavaScript!Кода вроде бы не стало меньше, но появилось другое преимущество: если функция используется в разных местах, то для изменения текста достаточно поправить только её определение. Чем сложнее задача и чем чаще она встречается, тем важнее выделять логику в отдельные функции.
Синтаксис определения
function имяФункции(параметры) {
тело;
}function greet(name) { ← ключевое слово, имя и параметр
return 'Hello, ' + name; ← тело функции
}Определение начинается с ключевого слова function, затем идёт имя функции (по тем же правилам, что и у переменных), в скобках — список параметров через запятую, а тело функции заключается в фигурные скобки {}.
Определить функцию — не значит вызвать её
Определение функции не запускает её код. Тело выполнится только при вызове. Посмотрите на пример:
function sayHi() {
console.log("Hi!");
}
console.log("Программа продолжается…");Здесь функция sayHi() определена, но её тело не выполняется — на экран попадёт только Программа продолжается…. Чтобы sayHi() сработала, её нужно явно вызвать:
function sayHi() {
console.log("Hi!");
}
sayHi(); // => Hi!
console.log("Программа продолжается…");Пример: функция для печати среднего арифметического
Реализуем функцию, которая вычисляет и печатает среднее арифметическое двух чисел. Среднее арифметическое — это сумма чисел, делённая на их количество. Например, среднее от 6 и 4: (6 + 4) / 2 = 5.
function printAverage(a, b) {
const total = a + b;
const average = total / 2;
console.log(average);
}
printAverage(6, 4); // => 5Здесь a и b — входные параметры, total содержит их сумму, average получается делением суммы на 2, а console.log() выводит результат.
Имена и порядок параметров
Имя параметра может быть любым — главное, чтобы оно отражало смысл значения, которое попадёт внутрь. С внешним кодом оно никак не связано:
function getLastChar(str) {
return str[str.length - 1];
}
// Внутри функции str будет равна 'Winter is coming'.
// Имя переменной снаружи не связано с именем параметра
const text = "Winter is coming";
console.log(getLastChar(text)); // => gКогда параметров два и больше, для большинства функций становится важен порядок их передачи. Если его поменять, функция отработает по-другому:
// Первый параметр — что ищем, второй — на что меняем
console.log("google".replace("go", "mo")); // => moogle
// Ничего не заменилось: внутри 'google' нет 'mo'
console.log("google".replace("mo", "go")); // => googleДругие формы записи
Функцию можно не только объявить через function, но и записать как значение и присвоить константе:
const sayHello = function (name) {
console.log(`Hello, ${name}!`);
};
sayHello("Hexlet"); // => Hello, Hexlet!Такую запись называют функциональным выражением. Обратите внимание на точку с запятой в конце: перед нами обычное присваивание константы, а не объявление функции.
У функционального выражения есть короткая форма, стрелочная. Слово function в ней заменяется на стрелку =>, которая ставится после списка параметров:
const sayHello = (name) => {
console.log(`Hello, ${name}!`);
};
sayHello("Hexlet"); // => Hello, Hexlet!Для наших задач все три записи равнозначны: функцию определяют, а потом вызывают по имени. Стрелочная форма в JavaScript встречается чаще остальных, поэтому дальше в курсе примеры записаны именно так. Отдельный урок этого модуля покажет, как сократить её ещё сильнее.
Переиспользование и читаемость
Функции помогают избегать дублирования и делают программы понятнее. Само название функции говорит, что она делает. Это особенно важно в больших проектах, где код читают другие программисты (или вы сами через месяц).
Задание
Сайт выводит приветствие для каждого посетителя. Реализуйте функцию sayHello(), которая выводит на экран фразу Hello, World!.
sayHello(); // => Hello, World!В задачах, где нужно реализовать функцию, вызывать её самим не нужно — это сделают автоматические тесты. Пример вызова показан лишь для того, чтобы вы понимали, как функция будет использоваться.
Примечание: в файле уже есть строка
export default …— она служебная, нужна системе проверки; что такое экспорт, разберём в уроке про модули.
Полезное
Ваше упражнение проверяется по этим тестам
// @ts-check
import { expect, test, vi } from "vitest";
import f from "./index.js";
test("define function", async () => {
const consoleLogSpy = vi.spyOn(console, "log");
f();
const firstArg = consoleLogSpy.mock.calls.join("\n");
expect(firstArg).toBe("Hello, World!");
});Решение учителя откроется через:
20:00
