Массив — это список значений под номерами. Пишется в квадратных скобках, элементы разделяются запятыми.
const fruits = ['яблоко', 'груша', 'слива']
fruits[0] // 'яблоко'
fruits[2] // 'слива'
fruits.length // 3Номера называются индексами, и счёт идёт с нуля. Первый элемент — [0],
второй — [1]. Поэтому последний элемент стоит под номером length - 1, а не
length.
length — это количество элементов. Скобок после него нет: это не действие, а
просто число, которое массив про себя знает.
Если спросить номер, которого нет, ошибки не будет:
fruits[99] // undefinedВы получите undefined — «тут ничего нет». Программа не упадёт, и опечатка в
номере всплывёт позже, в другом месте. Будьте внимательны с границами.
Добавить и снять с конца
const list = [1, 2]
list.push(3) // list теперь [1, 2, 3]
const last = list.pop() // last = 3, list снова [1, 2]push кладёт элемент в конец, pop снимает последний и возвращает его. Оба
метода меняют сам массив, а длина пересчитывается сама.
Заметьте: массив объявлен через const, а мы его меняем. Так можно. const
запрещает положить в переменную другой массив, но не запрещает менять
содержимое того, что уже лежит.
Обойти весь массив
Цикл for со счётчиком вам уже знаком. Счётчик и есть индекс:
const prices = [100, 250, 90]
for (let i = 0; i < prices.length; i++) {
console.log(i, prices[i])
}Условие i < prices.length, а не <=. Иначе на последнем круге вы спросите
prices[3] и получите undefined.
Если номер не нужен, удобнее for...of. Он сразу отдаёт сами значения:
for (const price of prices) {
console.log(price)
}Есть ли значение в списке
const prices = [100, 250, 90]
prices.includes(250) // true
prices.indexOf(90) // 2
prices.indexOf(7) // -1includes отвечает «да» или «нет». indexOf возвращает номер, а если ничего
не нашёл — минус единицу. Сравнение строгое, как у ===: число 2 и строка
'2' для них разные значения.
Ловушка: не ставьте indexOf прямо в if. Если элемент стоит первым,
indexOf вернёт 0, а ноль в условии считается ложью — «нашли» превратится в
«не нашли». Когда нужен ответ «есть или нет», берите includes.
slice и splice
Названия похожи, а поведение противоположное.
const queue = ['Аня', 'Боря', 'Вера', 'Гриша']
const part = queue.slice(1, 3)
// part = ['Боря', 'Вера'], queue не изменился
const removed = queue.splice(1, 2)
// removed = ['Боря', 'Вера'], queue теперь ['Аня', 'Гриша']slice(начало, конец) возвращает копию куска. Элемент под номером конец
в копию не входит. Исходный массив остаётся как был.
splice(начало, сколько) вырезает элементы из самого массива и возвращает
вырезанное. Оригинал после него другой.
Запомните так: splice режет оригинал, slice снимает копию.
Массив передаётся по ссылке
Вот классическая ошибка. Функция получила массив и что-то в нём поменяла:
function withoutFirst(list) {
list.splice(0, 1)
return list
}
const names = ['Аня', 'Боря', 'Вера']
const rest = withoutFirst(names)
// rest = ['Боря', 'Вера']
// names = ['Боря', 'Вера'] — тоже!В переменной лежит не сам массив, а ссылка на него — как адрес дома. При вызове функция получает копию адреса, но дом по этому адресу тот же самый. Поменяли что-то внутри — изменилось и снаружи.
Тот, кто позвал функцию, такого не ждёт. Поэтому хорошая функция не трогает переданный массив, а собирает новый:
function withoutFirst(list) {
return list.slice(1)
}Проверки в задачах этого урока будут смотреть и на это: не испортился ли массив, который вы получили.
Заглянем вперёд: map и filter
Собирать новый массив циклом приходится так часто, что для этого есть готовые методы. Им передают функцию, и они сами вызывают её для каждого элемента.
function double(n) {
return n * 2
}
function isBig(n) {
return n > 100
}
const prices = [100, 250, 90]
prices.map(double) // [200, 500, 180]
prices.filter(isBig) // [250]map складывает в новый массив то, что вернула функция для каждого элемента.
Длина результата та же, что у исходного. filter оставляет только те элементы,
для которых функция вернула true. Оба метода исходный массив не меняют.
Обратите внимание: мы пишем double, а не double(). Мы не вызываем функцию
сами, а отдаём её методу — он вызовет её сам.
Подробно о них поговорим позже. В задачах ниже вполне хватит цикла.
Теперь попробуйте сами. Код выполняется прямо в браузере — нажмите «Запустить», и увидите результат через миг.
Первый модуль пройден
Это был последний бесплатный урок. Посмотрите, что вы уже умеете: писать функции, хранить данные в переменных, ветвить код условиями, гонять циклы, разбирать строки и собирать списки в массивы. Этого хватает, чтобы решать небольшие задачи на чистом JavaScript.
Дальше язык раскрывается глубже:
- Объекты и данные. Объекты, копии и ссылки, деструктуризация, JSON и обработка ошибок.
- JavaScript глубже. Стрелочные функции и колбэки, замыкания, рекурсия,
thisи классы. - Асинхронность. Таймеры, цикл событий, промисы,
async/awaitиfetch. - Коллекции и модули.
Map,Setи разбиение кода на файлы. - Проекты. Список дел и игра «угадай число», собранные из всего пройденного.
Остальные модули открываются после покупки курса: один платёж, доступ навсегда. Купить можно на странице курса.