Поиск элемента
Вспомните ряд ячеек камеры хранения с номерами. Пока вы знаете номер ячейки, всё быстро: подходите и открываете нужную. Но бывает наоборот: вы помните, как выглядит сумка, а номер забыли. Тогда остаётся идти вдоль ряда и открывать ячейки по очереди, пока не найдётся своя.
Метод splice вырезает элементы по индексу. А индекс нужного элемента часто неизвестен: известно только значение, например цвет "green". Для такого поиска у массива есть два метода — indexOf и includes:
const colors = ["red", "green", "red"];
console.log(colors.indexOf("red")); // 0
console.log(colors.indexOf("blue")); // -1
console.log(colors.includes("green")); // true
console.log(colors.includes("blue")); // falseДавайте разберём по строкам:
colors.indexOf("red")печатает0: поиск идёт слева направо и останавливается на первом совпадении.- Второй
"red"с индексом2метод не замечает. colors.indexOf("blue")печатает-1: такого элемента нет.colors.includes("green")печатаетtrue, а для"blue"—false.
Два метода поиска
Оба метода обходят массив так же, как вы шли вдоль ячеек: от индекса 0 к концу. Различаются они тем, что возвращают.
indexOf
Метод indexOf отвечает на вопрос «где лежит?». Он возвращает индекс первого совпадения или -1, если элемента нет. Число -1 выбрано потому, что такого индекса в массиве не бывает.
Берите indexOf, когда индекс нужен дальше: чтобы прочитать соседний элемент или вырезать найденный.
includes
Метод includes отвечает на вопрос «есть ли?». Он возвращает true или false, и его удобно ставить прямо в условие if. Например, if (cart.includes("milk")) читается почти как фраза «если в корзине есть молоко».
Берите includes, когда место элемента не важно, а важен только сам факт.
Как они сравнивают
Тут аналогия с камерой хранения перестаёт работать. Свою сумку вы узнаете и в чужом чехле, а методы сравнивают строго. Оба сравнивают без приведения типов, как ===:
console.log([1, 2].indexOf("1")); // -1
console.log([1, 2].includes("1")); // false
console.log([NaN].indexOf(NaN)); // -1
console.log([NaN].includes(NaN)); // trueСтрока "1" не равна числу 1, поэтому её нет среди чисел. А с NaN методы расходятся:
indexOfсравнивает через===, аNaN === NaNдаётfalse, поэтомуNaNне находится;includesделает дляNaNисключение и находит его.
Чем indexOf отличается от includes, часто спрашивают на собеседовании. Короткий ответ: indexOf возвращает индекс или -1, includes возвращает true или false, и только includes находит NaN.
Найти и вырезать
Теперь соединим поиск со splice. Чтобы удалить "green", сначала узнаём его индекс, а затем вырезаем один элемент:
const i = colors.indexOf("green");
if (i !== -1) {
colors.splice(i, 1);
}
console.log(colors.join(" ")); // red redПроверка i !== -1 здесь обязательна. Без неё при отсутствии элемента получился бы вызов splice(-1, 1). А отрицательный индекс и здесь отсчитывается от конца, так что вырезался бы последний элемент.
Частая ошибка
Результат indexOf поставили прямо в условие:
const colors = ["red", "green"];
if (colors.indexOf("red")) { // ✗
console.log("found");
}Ошибки нет, но программа ничего не печатает. Элемент "red" стоит первым, и indexOf возвращает 0, а 0 — ложное значение. Зато для отсутствующего элемента -1 — истинное значение, и условие сработало бы.
Чтобы проверить, есть ли элемент, пишите colors.includes("red") или colors.indexOf("red") !== -1.
Главное
indexOfвозвращает индекс первого совпадения или-1, аincludes—trueилиfalse.- Оба сравнивают как
===, но толькоincludesнаходитNaN. - Перед
splice(i, 1)проверяйтеi !== -1: иначе вырежется последний элемент. - Результат
indexOfне ставят вifсам по себе: индекс0— ложное значение.
Подпишись, чтобы пройти курс
Курс бесплатный. Войди через Telegram и подпишись на канал — откроются все уроки.