Как избежать использования переменной результата в функции проверки массивов?
Что проверяют
Умеете ли вы писать проверки без лишнего состояния: флаг result, который меняется в цикле и возвращается в конце, это лишний источник ошибок. Следом обычно просят объяснить, чем отличаются every и some на пустом массиве и почему forEach здесь не подходит.
Как отвечать
Покажите исходный вариант с флагом и два способа от него уйти:
- ранний возврат: в
for...ofвозвращайте ответ сразу, как только он известен:if (!isValid(x)) return false;, а после циклаreturn true. Флага нет, лишних итераций тоже; every: истина, если условие выполнено для всех элементов. Останавливается на первомfalse;some: истина, если условие выполнено хотя бы для одного. Останавливается на первомtrue;findиfindIndex: когда нужен сам найденный элемент или его позиция, а не только да или нет;includes: наличие конкретного значения. Сравнивает по SameValueZero, поэтому находитNaN, в отличие отindexOf.
Итог выглядит так: const allPositive = (arr) => arr.every((n) => n > 0);. Функция из одного выражения, её легко прочитать и протестировать. Назовите граничный случай: [].every(fn) возвращает true, [].some(fn) возвращает false. Если по смыслу задачи пустой массив невалиден, это проверяется отдельно.
Про производительность скажите честно: на обычных объёмах разница между циклом и every не важна, выбирают по читаемости. Цикл выигрывает, когда внутри нужен await или логика с несколькими выходами.
Где спотыкаются
Пишут return false внутри forEach и ждут, что функция завершится. Этот return выходит только из колбэка, обход продолжается, а внешняя функция вернёт undefined.
Заменяют проверку на arr.filter(fn).length > 0. Результат верный, но массив проходится целиком и создаётся новый, хотя some остановился бы на первом совпадении.
Передают в every асинхронный колбэк. Промис всегда истинен, поэтому проверка «пройдёт» для любых данных. Для асинхронных условий нужен Promise.all или обычный цикл с await.