Next: примеры (JAVASCRIPT)
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 function2. Попытка повторного использования завершенного итератора: После 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().
Расширенные примеры применения
Создание пользовательского итератора:
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, на котором генератор приостановился.
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:
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 }Частичный обход коллекции:
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