В JavaScript функции могут быть вызваны с любым числом аргументов, независимо от того, сколько параметров было объявлено. Это создаёт гибкость, но требует механизма для работы с опциональными параметрами — параметрами, которые могут быть опущены при вызове функции.
В современном JavaScript опциональные параметры задаются с помощью значения по умолчанию:
function greet(name = "Гость") {
console.log(`Привет, ${name}!`);
}
greet(); // Привет, Гость!
greet("Анна"); // Привет, Анна!
Если аргумент не передан, используется значение по умолчанию. Этот
способ предпочтителен, так как делает код более читаемым и защищает от
undefined.
До появления значений по умолчанию часто использовалась проверка аргументов внутри функции:
function multiply(a, b) {
if (b === undefined) {
b = 1;
}
return a * b;
}
multiply(5); // 5
multiply(5, 2); // 10
Такой подход работает, но делает код более громоздким и менее очевидным.
argumentsВсе функции имеют локальную переменную arguments,
содержащую все переданные аргументы. Это позволяет создавать функции с
переменным числом параметров:
function sumAll() {
let total = 0;
for (let i = 0; i < arguments.length; i++) {
total += arguments[i];
}
return total;
}
sumAll(1, 2, 3, 4); // 10
Однако использование arguments считается устаревшим в
современном JavaScript, на смену приходит оператор
rest.
Синтаксис ... позволяет собирать остаток аргументов в
массив:
function sum(first, ...rest) {
let total = first;
for (const num of rest) {
total += num;
}
return total;
}
sum(1, 2, 3, 4); // 10
Преимущество оператора rest — явное указание, какие параметры
обязательны, а какие — вариативны, без необходимости вручную проверять
arguments.length.
TypeScript расширяет возможности JavaScript и позволяет явно
указывать опциональные параметры с помощью знака ?:
function greet(name?: string) {
if (name) {
console.log(`Привет, ${name}!`);
} else {
console.log("Привет, Гость!");
}
}
greet(); // Привет, Гость!
greet("Анна"); // Привет, Анна!
С точки зрения TypeScript, это повышает безопасность типов и предотвращает ошибки при вызове функции без аргументов.
undefinedДаже если параметр объявлен без значения по умолчанию, передача
undefined эквивалентна его отсутствию:
function greet(name = "Гость") {
console.log(`Привет, ${name}!`);
}
greet(undefined); // Привет, Гость!
greet(null); // Привет, null!
Важно различать undefined и null:
undefined активирует значение по умолчанию,
null — нет.
Параметры с дефолтными значениями или опциональные должны идти после обязательных параметров. Иначе синтаксис будет некорректным:
function createUser(name, age = 18) {
return { name, age };
}
createUser("Иван"); // { name: "Иван", age: 18 }
createUser("Иван", 25); // { name: "Иван", age: 25 }
Попытка поставить обязательный параметр после опционального приведёт к ошибке:
function wrong(age = 18, name) {} // Ошибка
Если функция имеет множество опциональных параметров, удобно передавать их через объект:
function configure(options) {
const { width = 100, height = 200, color = "red" } = options;
console.log(width, height, color);
}
configure({ width: 150 }); // 150 200 red
configure({}); // 100 200 red
Это делает код более читаемым и предотвращает ошибки при изменении числа параметров.
Стрелочные функции поддерживают значения по умолчанию так же, как обычные функции:
const greet = (name = "Гость") => `Привет, ${name}!`;
greet(); // Привет, Гость!
greet("Анна"); // Привет, Анна!
Вариативные параметры с оператором rest также работают в стрелочных функциях:
const sum = (...numbers) => numbers.reduce((a, b) => a + b, 0);
sum(1, 2, 3); // 6
Опциональные параметры могут сочетаться с деструктуризацией объектов и массивов:
function display({ name = "Гость", age = 18 } = {}) {
console.log(`${name}, ${age}`);
}
display({ name: "Анна" }); // Анна, 18
display(); // Гость, 18
Использование значения по умолчанию для всего параметра
{} предотвращает ошибку при вызове функции без
аргументов.
? для безопасного контроля типов.