Next: примеры (JAVASCRIPT)

Использование next() для управления итерацией в JS
Раздел: Итераторы, Протокол итератора
next: Object

Основные сведения о методе next() в JavaScript

В JavaScript next() является методом объекта-итератора, а не отдельной глобальной функцией. Он используется для ручного перебора элементов итерируемых объектов, таких как массивы, строки, Map, Set, а также для работы с генераторами.

Метод вызывается у объекта, возвращаемого методом Symbol.iterator, и не принимает аргументов.

При каждом вызове метод next() возвращает объект с двумя свойствами:

  • value: значение текущего элемента последовательности.
  • done: булевый флаг, указывающий на завершение итерации (true – итерация завершена, false – есть следующие значения).

После завершения итерации (когда done: true) свойство value обычно равно undefined, но может содержать возвращаемое значение генератора.

Простые примеры использования

Пример с массивом:

const arr = ['я', 'иду', 'гулять'];
const iterator = arr[Symbol.iterator]();

console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
// Результат:
// { value: 'я', done: false }
// { value: 'иду', done: false }
// { value: 'гулять', done: false }
// { value: undefined, done: true }

Пример с генератором:

function* count() {
  yield 1;
  yield 2;
  return 3;
}
const gen = count();

console.log(gen.next());
console.log(gen.next());
console.log(gen.next());
console.log(gen.next());
// Результат:
// { value: 1, done: false }
// { value: 2, done: false }
// { value: 3, done: true } // value содержит возвращаемое значение
// { value: undefined, done: true }

Альтернативные методы итерации в JavaScript

  • for...of: Цикл для автоматического перебора итерируемых объектов. Предпочтительнее для простого последовательного чтения всех значений, так как избавляет от ручного вызова next() и проверки done.
  • Array.prototype.forEach(): Метод для перебора массивов с передачей колбэка. Удобен для массивов, но работает только с ними, а не с любыми итерируемыми объектами.
  • Spread оператор (...) и Array.from(): Могут конвертировать итерируемый объект в массив, после чего с ним можно работать обычными методами массивов. Используются, когда нужна именно коллекция значений, а не пошаговый контроль.

Метод next() предпочтителен при необходимости тонкого контроля над процессом итерации, например, для получения не всех элементов подряд, а по условию, или в связке с генераторами.

Аналоги в других языках программирования

Python: Используется функция next(), которая принимает итератор. Аналогично возвращает следующее значение и вызывает исключение StopIteration при завершении. Можно задать значение по умолчанию вторым аргументом.

# Python
my_list = [10, 20, 30]
iter_obj = iter(my_list)
print(next(iter_obj))  # 10
print(next(iter_obj))  # 20
print(next(iter_obj, 'Конец'))  # 30
print(next(iter_obj, 'Конец'))  # 'Конец'

PHP: Интерфейс Iterator требует реализации метода next() для перехода к следующему элементу. Текущий элемент получают через current(), а флаг завершения проверяют valid().

// PHP
$arr = new ArrayIterator(['a', 'b', 'c']);
$arr->next(); // Перемещает указатель
echo $arr->current(); // 'b'

C++: Для итераторов стандартной библиотеки (STL) используется оператор инкремента (++) для перехода к следующему элементу, а оператор разыменования (*) для получения значения. Конец проверяется сравнением с end().

Ключевое отличие JavaScript – метод next() возвращает и значение, и флаг завершения в одном объекте, что делает его самодостаточным для контроля итерации.

Типичные ошибки

1. Вызов next() у неитерируемого объекта:

const obj = { a: 1 };
const iterator = obj[Symbol.iterator](); // TypeError: obj[Symbol.iterator] is not a function

2. Попытка повторного использования завершенного итератора: После done: true последующие вызовы next() всегда возвращают { value: undefined, done: true }, что может быть неочевидно.

const arr = [1];
const iter = arr[Symbol.iterator]();
console.log(iter.next()); // { value: 1, done: false }
console.log(iter.next()); // { value: undefined, done: true }
console.log(iter.next()); // { value: undefined, done: true } // Ожидания нового значения нет

3. Использование next() напрямую у коллекции, а не у её итератора:

const set = new Set([1, 2]);
// set.next(); // TypeError: set.next is not a function - правильно: set[Symbol.iterator]().next()

История изменений

Метод next() как часть протокола итераторов был стандартизирован в спецификации ECMAScript 2015 (ES6). С тех пор его спецификация остается стабильной.

Основное эволюционное изменение связано не с самим методом, а с контекстом его появления – введением протоколов итерируемых объектов и генераторов, которые и предоставляют метод next().

Расширенные примеры применения

Создание пользовательского итератора:

Пример javascript
const range = {
  from: 1,
  to: 3,
  [Symbol.iterator]() {
    this.current = this.from;
    return this;
  },
  next() {
    if (this.current <= this.to) {
      return { done: false, value: this.current++ };
    } else {
      return { done: true };
    }
  }
};

const it = range[Symbol.iterator]();
console.log(it.next()); // { done: false, value: 1 }
console.log(it.next()); // { done: false, value: 2 }
console.log(it.next()); // { done: false, value: 3 }
console.log(it.next()); // { done: true }

Передача значения в next() генератора: В метод next() генератора можно передать аргумент, который становится результатом выражения yield, на котором генератор приостановился.

Пример javascript
function* ask() {
  const name = yield 'Как вас зовут?';
  const age = yield `Привет, ${name}. Сколько вам лет?`;
  return `${name}, вам ${age} лет.`;
}

const gen = ask();
console.log(gen.next().value);       // 'Как вас зовут?'
console.log(gen.next('Анна').value); // 'Привет, Анна. Сколько вам лет?'
console.log(gen.next(30).value);     // 'Анна, вам 30 лет.'

Итерация по Map:

Пример javascript
const map = new Map([
  ['name', 'Иван'],
  ['age', 25]
]);
const mapIterator = map[Symbol.iterator](); // Аналогично map.entries()

console.log(mapIterator.next()); // { value: ['name', 'Иван'], done: false }
console.log(mapIterator.next()); // { value: ['age', 25], done: false }
console.log(mapIterator.next()); // { value: undefined, done: true }

Частичный обход коллекции:

Пример javascript
const numbers = [10, 20, 30, 40, 50];
const numIter = numbers[Symbol.iterator]();

let result = numIter.next();
while (!result.done && result.value < 35) {
  console.log(`Обрабатываем: ${result.value}`);
  result = numIter.next();
}
console.log('Остановились на:', result.value); // 40
// Результат:
// Обрабатываем: 10
// Обрабатываем: 20
// Обрабатываем: 30
// Остановились на: 40

JS next function comments

En
Next Returns an object with value and done properties representing the next value in the iteration