← Назад к вопросам

Зачем нужен rest оператор?

1.3 Junior🔥 191 комментариев
#JavaScript Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

REST оператор (...): Назначение и применение

REST оператор (Rest Parameter Operator) обозначается тремя точками (...) и является одной из наиболее полезных возможностей современного JavaScript. Он решает проблему работы с неизвестным или переменным количеством аргументов функции и элементов массива.

История и контекст

REST оператор был введен в ES6 (ES2015) как часть спецификации ECMAScript. Его название происходит от слова "rest" (остаток), потому что он собирает остаток элементов или аргументов в один массив.

Основные применения REST оператора

1. Функции с переменным количеством аргументов

До ES6 приходилось использовать объект arguments:

// Старый способ (не рекомендуется)
function sum() {
  let total = 0;
  for (let i = 0; i < arguments.length; i++) {
    total += arguments[i];
  }
  return total;
}

console.log(sum(1, 2, 3, 4, 5)); // 15

// Новый способ с REST оператором (правильно)
function sumNew(...numbers) {
  return numbers.reduce((acc, num) => acc + num, 0);
}

console.log(sumNew(1, 2, 3, 4, 5)); // 15

Преимущества REST оператора:

  • numbers это настоящий массив, можно использовать методы массива
  • Более читаемый и понятный код
  • Работает с стрелочными функциями

2. Комбинирование REST с обычными параметрами

function greetPeople(greeting, ...names) {
  names.forEach(name => {
    console.log(`${greeting}, ${name}!`);
  });
}

greetPeople('Привет', 'Иван', 'Мария', 'Петр');
// Привет, Иван!
// Привет, Мария!
// Привет, Петр!

function createUser(id, name, ...emails) {
  return {
    id,
    name,
    emails,
    emailCount: emails.length
  };
}

const user = createUser(1, 'John', 'john@gmail.com', 'john@work.com', 'john@personal.com');
console.log(user);
// { id: 1, name: 'John', emails: ['john@gmail.com', 'john@work.com', 'john@personal.com'], emailCount: 3 }

Важное правило: REST параметр должен быть последним в списке параметров.

3. Разворачивание массивов (Spread в функции)

const numbers = [1, 2, 3, 4, 5];
const moreNumbers = [6, 7, 8];

// Объединение массивов
const combined = [...numbers, ...moreNumbers];
console.log(combined); // [1, 2, 3, 4, 5, 6, 7, 8]

// Передача массива как аргументов функции
Math.max(...numbers); // 5 (вместо Math.max(1, 2, 3, 4, 5))

// Создание копии массива
const copy = [...numbers];
copу.push(999);
console.log(numbers); // [1, 2, 3, 4, 5] — исходный не изменился

4. Деструктуризация массивов с REST

const [first, second, ...rest] = [1, 2, 3, 4, 5, 6];

console.log(first);  // 1
console.log(second); // 2
console.log(rest);   // [3, 4, 5, 6]

// Пропуск элементов
const [a, , c, ...remaining] = [10, 20, 30, 40, 50];
console.log(a);         // 10
console.log(c);         // 30
console.log(remaining); // [40, 50]

5. Деструктуризация объектов с REST

const person = {
  name: 'Иван',
  age: 30,
  city: 'Москва',
  country: 'Россия',
  job: 'Frontend разработчик'
};

const { name, age, ...otherInfo } = person;

console.log(name);      // 'Иван'
console.log(age);       // 30
console.log(otherInfo); // { city: 'Москва', country: 'Россия', job: 'Frontend разработчик' }

// Полезно для фильтрации свойств
const { password, ...safeUser } = userData; // Исключаем пароль

6. REST в параметрах React компонента

function Button({ type, disabled, ...props }) {
  return (
    <button
      type={type}
      disabled={disabled}
      className="btn"
      {...props}
    >
      Клик
    </button>
  );
}

// Использование
<Button
  type="submit"
  disabled={false}
  onClick={handleSubmit}
  className="primary"
  id="submit-btn"
/>

7. Объединение и копирование объектов

const defaults = {
  timeout: 5000,
  retries: 3,
  headers: {}
};

const userConfig = {
  timeout: 10000,
  headers: { 'Authorization': 'Bearer token' }
};

// Мерж конфигурации (Spread в объектах)
const finalConfig = { ...defaults, ...userConfig };

console.log(finalConfig);
// {
//   timeout: 10000,
//   retries: 3,
//   headers: { 'Authorization': 'Bearer token' }
// }

REST vs Spread: В чём разница?

// REST - собирает элементы в массив/объект (слева от =)
function test(...args) { } // REST
const [a, ...rest] = [1, 2, 3]; // REST
const { x, ...other } = obj; // REST

// SPREAD - разворачивает массив/объект (использует элементы)
const arr = [...[1, 2, 3]]; // SPREAD
Math.max(...[1, 2, 3]); // SPREAD
const obj = { ...someObject }; // SPREAD

Практические примеры

Создание функции фильтрации аргументов

function filterNumbers(...items) {
  return items.filter(item => typeof item === 'number');
}

console.log(filterNumbers(1, 'hello', 2, true, 3, null, 4));
// [1, 2, 3]

Работа с переменным количеством данных

function createQuery(baseUrl, ...segments) {
  const path = segments.join('/');
  return `${baseUrl}/${path}`;
}

const url = createQuery('https://api.example.com', 'users', 'profile', '123');
console.log(url);
// https://api.example.com/users/profile/123

Заключение

REST оператор — это фундаментальная возможность современного JavaScript, которая делает код более гибким и читаемым. Он позволяет работать с неизвестным количеством аргументов и элементов, упрощает деструктуризацию и создание копий структур данных. Понимание REST оператора критически важно для современной разработки на JavaScript и используется повсеместно в React, Node.js и других фреймворках.

Зачем нужен rest оператор? | PrepBro