Урок 02

Параметры и аргументы

Параметры — переменные в объявлении функции. Аргументы — значения, переданные при вызове.

Базовый пример

function add(a, b) {   // a, b — параметры
    return a + b;
}

add(2, 3);             // 2, 3 — аргументы

Значения по умолчанию

function greet(name = 'Гость') {
    return `Привет, ${name}`;
}

greet();         // Привет, Гость
greet('Алиса');  // Привет, Алиса
greet(undefined); // Привет, Гость
greet(null);     // Привет, null

undefined активирует дефолт, null — нет.

Дефолт — это выражение

Вычисляется при каждом вызове, если параметр undefined:

function createUser(name, createdAt = new Date()) {
    return { name, createdAt };
}

Может зависеть от других параметров:

function greet(name, greeting = `Привет, ${name}`) {
    return greeting;
}

Rest-параметры

Собирают все аргументы в массив:

function sum(...numbers) {
    return numbers.reduce((a, b) => a + b, 0);
}

sum(1, 2, 3);      // 6
sum(1, 2, 3, 4, 5); // 15

Rest всегда последний:

function log(level, ...messages) {
    console.log(`[${level}]`, ...messages);
}

Spread при вызове

const numbers = [1, 2, 3];
sum(...numbers);

Math.max(...numbers);

arguments (устаревшее)

Доступно в обычных функциях (не в стрелочных):

function oldSum() {
    let total = 0;
    for (let i = 0; i < arguments.length; i++) {
        total += arguments[i];
    }
    return total;
}

arguments — не настоящий массив. Не используй в новом коде — есть rest.

Деструктуризация в параметрах

function print({ name, age }) {
    console.log(name, age);
}

print({ name: 'Алиса', age: 25 });

Со значениями по умолчанию:

function print({ name = 'Гость', age = 0 } = {}) {
    console.log(name, age);
}

print({});        // Гость 0
print();          // Гость 0
print({ name: 'Алиса' }); // Алиса 0

Массив:

function printCoords([x, y]) {
    console.log(x, y);
}

printCoords([10, 20]);

Передача по значению

Примитивы передаются по значению (копия):

function change(x) {
    x = 100;
}

let n = 5;
change(n);
n; // 5

Объекты — по ссылке:

function change(obj) {
    obj.name = 'Боб';
}

const user = { name: 'Алиса' };
change(user);
user.name; // 'Боб'

Но переприсвоение внутри функции не влияет на внешнюю переменную:

function change(obj) {
    obj = { name: 'Боб' };
}

const user = { name: 'Алиса' };
change(user);
user.name; // 'Алиса'

Сколько аргументов

Лишние аргументы игнорируются, недостающие — undefined:

function add(a, b) {
    return a + b;
}

add(1, 2, 3); // 3, третий проигнорирован
add(1);       // NaN, b = undefined

Именованные аргументы (паттерн)

function createUser({ name, age, email }) {
    return { name, age, email };
}

createUser({ name: 'Алиса', age: 25, email: 'a@b.com' });

Плюсы: порядок не важен, легко пропустить опциональные.

Итоги

  • Параметры — в объявлении, аргументы — при вызове
  • Дефолты через =
  • Rest собирает в массив
  • Spread раскрывает
  • Примитивы — по значению, объекты — по ссылке
  • arguments устарело