Базовые операторы, математика
Многие операторы знакомы нам ещё со школы: сложение + , умножение * , вычитание — и так далее.
В этой главе мы начнём с простых операторов, а потом сконцентрируемся на специфических для JavaScript аспектах, которые не проходят в школьном курсе арифметики.
Термины: «унарный», «бинарный», «операнд»
Прежде, чем мы двинемся дальше, давайте разберёмся с терминологией.
- Операнд – то, к чему применяется оператор. Например, в умножении 5 * 2 есть два операнда: левый операнд равен 5 , а правый операнд равен 2 . Иногда их называют «аргументами» вместо «операндов».
- Унарным называется оператор, который применяется к одному операнду. Например, оператор унарный минус «-» меняет знак числа на противоположный:
let x = 1; x = -x; alert( x ); // -1, применили унарный минус
let x = 1, y = 3; alert( y - x ); // 2, бинарный минус вычитает значения
Математика
Поддерживаются следующие математические операторы:
- Сложение + ,
- Вычитание — ,
- Умножение * ,
- Деление / ,
- Взятие остатка от деления % ,
- Возведение в степень ** .
Первые четыре оператора очевидны, а про % и ** стоит сказать несколько слов.
Взятие остатка %
Оператор взятия остатка % , несмотря на обозначение, никакого отношения к процентам не имеет.
Результат a % b – это остаток от целочисленного деления a на b .
alert( 5 % 2 ); // 1, остаток от деления 5 на 2 alert( 8 % 3 ); // 2, остаток от деления 8 на 3 alert( 8 % 4 ); // 0, остаток от деления 8 на 4
Возведение в степень **
Оператор возведения в степень a ** b возводит a в степень b .
В школьной математике мы записываем это как a b .
alert( 2 ** 2 ); // 2² = 4 alert( 2 ** 3 ); // 2³ = 8 alert( 2 ** 4 ); // 2⁴ = 16
Математически, оператор работает и для нецелых чисел. Например, квадратный корень является возведением в степень ½:
alert( 4 ** (1/2) ); // 2 (степень 1/2 эквивалентна взятию квадратного корня)
Сложение строк при помощи бинарного +
Давайте рассмотрим специальные возможности операторов JavaScript, которые выходят за рамки школьной арифметики.
Обычно при помощи плюса ‘+’ складывают числа.
Но если бинарный оператор ‘+’ применить к строкам, то он их объединяет в одну:
let s = "моя" + "строка"; alert(s); // моястрока
Обратите внимание, если хотя бы один операнд является строкой, то второй будет также преобразован в строку.
alert( '1' + 2 ); // "12" alert( 2 + '1' ); // "21"
Как видите, не важно, первый или второй операнд является строкой.
Вот пример посложнее:
alert(2 + 2 + '1' ); // будет "41", а не "221"
Здесь операторы работают один за другим. Первый + складывает два числа и возвращает 4 , затем следующий + объединяет результат со строкой, производя действие 4 + ‘1’ = ’41’ .
Сложение и преобразование строк — это особенность бинарного плюса + . Другие арифметические операторы работают только с числами и всегда преобразуют операнды в числа.
Например, вычитание и деление:
alert( 6 - '2' ); // 4, '2' приводится к числу alert( '6' / '2' ); // 3, оба операнда приводятся к числам
Приведение к числу, унарный +
Плюс + существует в двух формах: бинарной, которую мы использовали выше, и унарной.
Унарный, то есть применённый к одному значению, плюс + ничего не делает с числами. Но если операнд не число, унарный плюс преобразует его в число.
// Не влияет на числа let x = 1; alert( +x ); // 1 let y = -2; alert( +y ); // -2 // Преобразует не числа в числа alert( +true ); // 1 alert( +"" ); // 0
На самом деле это то же самое, что и Number(. ) , только короче.
Необходимость преобразовывать строки в числа возникает очень часто. Например, обычно значения полей HTML-формы — это строки. А что, если их нужно, к примеру, сложить?
Бинарный плюс сложит их как строки:
let apples = "2"; let oranges = "3"; alert( apples + oranges ); // "23", так как бинарный плюс объединяет строки
Поэтому используем унарный плюс, чтобы преобразовать к числу:
let apples = "2"; let oranges = "3"; // оба операнда предварительно преобразованы в числа alert( +apples + +oranges ); // 5 // более длинный вариант // alert( Number(apples) + Number(oranges) ); // 5
С точки зрения математика, такое изобилие плюсов выглядит странным. Но с точки зрения программиста тут нет ничего особенного: сначала выполнятся унарные плюсы, которые приведут строки к числам, а затем бинарный ‘+’ их сложит.
Почему унарные плюсы выполнились до бинарного сложения? Как мы сейчас увидим, дело в их приоритете.
Приоритет операторов
В том случае, если в выражении есть несколько операторов – порядок их выполнения определяется приоритетом, или, другими словами, существует определённый порядок выполнения операторов.
Из школы мы знаем, что умножение в выражении 1 + 2 * 2 выполнится раньше сложения. Это как раз и есть «приоритет». Говорят, что умножение имеет более высокий приоритет, чем сложение.
Скобки важнее, чем приоритет, так что, если мы не удовлетворены порядком по умолчанию, мы можем использовать их, чтобы изменить приоритет. Например, написать (1 + 2) * 2 .
В JavaScript много операторов. Каждый оператор имеет соответствующий номер приоритета. Тот, у кого это число больше, – выполнится раньше. Если приоритет одинаковый, то порядок выполнения – слева направо.
Отрывок из таблицы приоритетов (нет необходимости всё запоминать, обратите внимание, что приоритет унарных операторов выше, чем соответствующих бинарных):
| Приоритет | Название | Обозначение |
|---|---|---|
| … | … | … |
| 15 | унарный плюс | + |
| 15 | унарный минус | — |
| 14 | возведение в степень | ** |
| 13 | умножение | * |
| 13 | деление | / |
| 12 | сложение | + |
| 12 | вычитание | — |
| … | … | … |
| 2 | присваивание | = |
| … | … | … |
Так как «унарный плюс» имеет приоритет 15 , который выше, чем 12 у «сложения» (бинарный плюс), то в выражении «+apples + +oranges» сначала выполнятся унарные плюсы, а затем сложение.
Присваивание
Давайте отметим, что в таблице приоритетов также есть оператор присваивания = . У него один из самых низких приоритетов: 2 .
Именно поэтому, когда переменной что-либо присваивают, например, x = 2 * 2 + 1 , то сначала выполнится арифметика, а уже затем произойдёт присваивание = с сохранением результата в x .
let x = 2 * 2 + 1; alert( x ); // 5
Присваивание = возвращает значение
Тот факт, что = является оператором, а не «магической» конструкцией языка, имеет интересные последствия.
Большинство операторов в JavaScript возвращают значение. Для некоторых это очевидно, например сложение + или умножение * . Но и оператор присваивания не является исключением.
Вызов x = value записывает value в x и возвращает его.
Благодаря этому присваивание можно использовать как часть более сложного выражения:
let a = 1; let b = 2; let c = 3 - (a = b + 1); alert( a ); // 3 alert( c ); // 0
В примере выше результатом (a = b + 1) будет значение, которое присваивается переменной a (то есть 3 ). Потом оно используется для дальнейших вычислений.
Забавное применение присваивания, не так ли? Нам нужно понимать, как это работает, потому что иногда это можно увидеть в JavaScript-библиотеках.
Однако писать самим в таком стиле не рекомендуется. Такие трюки не сделают ваш код более понятным или читабельным.
Присваивание по цепочке
Рассмотрим ещё одну интересную возможность: цепочку присваиваний.
let a, b, c; a = b = c = 2 + 2; alert( a ); // 4 alert( b ); // 4 alert( c ); // 4
Такое присваивание работает справа налево. Сначала вычисляется самое правое выражение 2 + 2 , и затем результат присваивается переменным слева: c , b и a . В конце у всех переменных будет одно значение.
Опять-таки, чтобы код читался легче, лучше разделять подобные конструкции на несколько строчек:
c = 2 + 2; b = c; a = c;
Польза от такого стиля особенно ощущается при быстром просмотре кода.
Сокращённая арифметика с присваиванием
Часто нужно применить оператор к переменной и сохранить результат в ней же.
let n = 2; n = n + 5; n = n * 2;
Эту запись можно укоротить при помощи совмещённых операторов += и *= :
let n = 2; n += 5; // теперь n = 7 (работает как n = n + 5) n *= 2; // теперь n = 14 (работает как n = n * 2) alert( n ); // 14
Подобные краткие формы записи существуют для всех арифметических и побитовых операторов: /= , -= , **= и так далее.
Вызов с присваиванием имеет в точности такой же приоритет, как обычное присваивание, то есть выполнится после большинства других операций:
let n = 2; n *= 3 + 5; alert( n ); // 16 (сначала выполнится правая часть, выражение идентично n *= 8)
Инкремент/декремент
Одной из наиболее частых числовых операций является увеличение или уменьшение на единицу.
Для этого существуют даже специальные операторы:
-
Инкремент ++ увеличивает переменную на 1:
let counter = 2; counter++; // работает как counter = counter + 1, просто запись короче alert( counter ); // 3
let counter = 2; counter--; // работает как counter = counter - 1, просто запись короче alert( counter ); // 1
Инкремент/декремент можно применить только к переменной. Попытка использовать его на значении, типа 5++, приведёт к ошибке.
Операторы ++ и — могут быть расположены не только после, но и до переменной.
- Когда оператор идёт после переменной — это «постфиксная форма»: counter++ .
- «Префиксная форма» — это когда оператор идёт перед переменной: ++counter .
Обе эти инструкции делают одно и то же: увеличивают counter на 1 .
Есть ли разница между ними? Да, но увидеть её мы сможем, только если будем использовать значение, которое возвращают ++/— .
Давайте проясним этот момент. Как мы знаем, все операторы возвращают значение. Операторы инкремента/декремента не исключение. Префиксная форма возвращает новое значение, в то время как постфиксная форма возвращает старое (до увеличения/уменьшения числа).
Чтобы увидеть разницу, вот небольшой пример:
let counter = 1; let a = ++counter; // (*) alert(a); // 2
В строке (*) префиксная форма ++counter увеличивает counter и возвращает новое значение 2 . Так что alert покажет 2 .
Теперь посмотрим на постфиксную форму:
let counter = 1; let a = counter++; // (*) меняем ++counter на counter++ alert(a); // 1
В строке (*) постфиксная форма counter++ также увеличивает counter , но возвращает старое значение (которое было до увеличения). Так что alert покажет 1 .
-
Если результат оператора не используется, а нужно только увеличить/уменьшить переменную, тогда без разницы, какую форму использовать:
let counter = 0; counter++; ++counter; alert( counter ); // 2, обе строки сделали одно и то же
Операторы spread и rest в React
Если вы работали с ванильным JavaScript или React, то могли видеть в коде три точки — . . Так обозначаются операторы spread и rest. Они используют одинаковый синтаксис, но решают разные задачи.
Что такое оператор spread
Оператор spread — это конструкция в JavaScript, которая позволяет передавать элементы массива или свойства объекта в виде отдельных аргументов.
В React этот оператор часто используется для передачи пропсов в компоненты — это помогает избежать дублирования кода. Например, у нас есть компонент, который принимает несколько пропсов:
function MyComponent(props) < return ( ); >
С помощью оператора spread мы можем передать пропсы из объекта myProps в компонент MyComponent :
const myProps = < title: "Заголовок", description: "Описание" >; function App() < return />; >
☝ Научитесь работать с React на нашем курсе «Вёрстка React-компонентов».
Что такое оператор rest
Оператор rest — это синтаксическая конструкция в JavaScript, которая позволяет собирать оставшиеся элементы массива в другой массив или собирать оставшиеся свойства объекта в другой объект. Он всегда идёт последним и может использоваться только раз при одной операции «распаковки» массива или объекта.
В React оператор rest используется для работы с пропсами в компонентах. Например, с его помощью можно извлекать только нужные свойства из объекта пропсов и сохранять оставшиеся свойства в отдельный объект. Затем с помощью оператора spread мы можем передать оставшиеся пропсы в дочерние компоненты.
function MyComponent(< title, description, . childProps >) < return ( />
); >
На первой строке мы используем оператор rest — < title, description, . childProps >. Он помогает сохранить все пропсы, кроме title и description , в отдельный объект. А на шестой строке мы передаём их в ChildComponent с помощью spread.
Как отличить spread от rest
Операторы легко отличить. Когда синтаксис . используется для «распаковки» элементов массива или объекта в отдельные аргументы — это spread. А если три точки используются для сбора оставшихся аргументов в массив или объект — это оператор rest.
Материалы по теме
- Зачем фронтендерам React
- Сравнение Vue, React и Angular
- Зачем нужен CSS-in-JS
«Доктайп» — журнал о фронтенде. Читайте, слушайте и учитесь с нами.
Читать дальше
ChatGPT не справляется
Притворитесь нейросетью и решите 101 задачку по JavaScript как можно быстрее.
- 2 ноября 2023

Знакомство с JavaScript
Теперь, когда вы знаете, как создать структуру веб-страницы с помощью HTML и оформить ее стилями с помощью CSS, пришло время оживить её с помощью JavaScript (JS). JavaScript — это мощный язык программирования, который используется для создания интерактивных и динамических веб-сайтов.
Что такое JavaScript?
JavaScript — это язык сценариев, который позволяет вам создавать динамически обновляемый контент, управлять мультимедиа, анимировать изображения и многое другое. Почти все современные веб-сайты используют JavaScript для улучшения пользовательского опыта.
Подключение JavaScript к веб-странице
Вы можете добавить JavaScript в ваш HTML-документ двумя способами:
Встроенный JavaScript: непосредственно в HTML-документ, в тегах :
Внешний JavaScript: подключение внешнего .js файла к HTML-документу:
Основы синтаксиса JavaScript
JavaScript состоит из инструкций, которые выполняются компьютером. Вот пример простого синтаксиса:
var message = "Привет, мир!"; alert(message);
Переменные
Переменные в JavaScript — это контейнеры для хранения данных. Вы можете думать о них как о ящиках, на которых есть имена. Переменные объявляются с помощью ключевых слов var , let и const .
var name = "Алиса"; // Старый способ объявления переменной let age = 25; // Современный способ объявления переменной const pi = 3.14; // Константа, значение которой нельзя изменить
Функции
Функции — это блоки кода, предназначенные для выполнения конкретной задачи. Они могут принимать параметры и возвращать значение.
function sayHello(name) < alert("Привет, " + name); >sayHello("Мир");
События
События в JavaScript позволяют реагировать на действия пользователя. Например, клик мыши или нажатие клавиши.
document.getElementById("myButton").onclick = function() < alert("Кнопка была нажата!"); >;
Условия и циклы
JavaScript также поддерживает условные операторы и циклы для управления потоком выполнения кода.
if (age > 18) < alert("Вы совершеннолетний!"); >else < alert("Вы ещё не совершеннолетний!"); >for (let i = 0; i
Объекты и массивы
Объекты представляют собой коллекции данных, а массивы позволяют хранить упорядоченные коллекции данных.
let person = < name: "Джон", age: 30 >; let numbers = [1, 2, 3, 4, 5];
Отметим, что JavaScript не просто добавляет интерактивность к вашим веб-страницам, он также вносит логику и динамичность в ваш сайт. И вот почему это возможно.
Объекты Document Object Model (DOM)
DOM (объектная модель документа) — описывает структуру документа и позволяет программам изменять структуру, стиль и содержание веб-страниц. JavaScript может использовать DOM для манипуляции элементами и атрибутами.
document.getElementById("demo").innerHTML = "Привет, DOM!";
Обработка событий
События играют ключевую роль в интерактивности веб-сайтов. JavaScript может отслеживать действия пользователя, такие как клики мышью, нажатия клавиш, перемещения мыши и многие другие.
document.getElementById("myButton").addEventListener("click", function() < alert("Кнопка нажата!"); >);
JSON (JavaScript Object Notation)
JSON — это формат обмена данными, легко читаемый как людьми, так и машинами. В JavaScript вы можете легко преобразовывать объекты в JSON и обратно.
let jsonObject = JSON.stringify(< name: "Джон", age: 30 >); let jsObject = JSON.parse(jsonObject);
Асинхронность
JavaScript часто используется для асинхронных операций, таких как загрузка данных из интернета без перезагрузки страницы. Промисы и асинхронные функции ( async/await ) являются современными способами работы с асинхронным кодом.
fetch('https://api.example.com/data') .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error(error));
Замыкания
Замыкания позволяют функции доступ к переменным из области, в которой она была создана, даже после того как эта область перестала существовать. Это мощная концепция в JavaScript для управления приватностью и состоянием.
function createCounter() < let count = 0; return function() < count += 1; return count; >; > const counter = createCounter(); console.log(counter()); // 1 console.log(counter()); // 2
Современный синтаксис ES6+
Современный JavaScript включает множество улучшений синтаксиса и новых возможностей, таких как стрелочные функции, классы, шаблонные строки и деструктуризация.
// Стрелочная функция const greet = name => `Привет, $!`; // Класс class Person < constructor(name) < this.name = name; >sayHello() < return `Привет, $!`; > > // Деструктуризация const < name, age >= < name: "Джон", age: 30 >;
Подводя итог, JavaScript — это только начало вашего путешествия в создание интерактивных веб-сайтов. Продолжайте изучать и экспериментировать, и вскоре вы сможете создавать сложные веб-приложения.
В следующих статьях мы углубимся в различные аспекты JavaScript, включая современный синтаксис ES6+, асинхронное программирование и работу с фреймворками, такими как React или Vue.
- 1 ноября 2023

Событие onclick в JS на примерах
Интерактивность — ключевой компонент любого современного сайта. И одним из наиболее часто используемых событий для создания интерактивности является событие onclick . В этой статье мы подробно разберёмся, что такое событие onclick , как его использовать и приведем примеры применения.
Событие onclick — это событие JavaScript, которое активируется, когда пользователь кликает на определенный элемент страницы. Это может быть кнопка, ссылка, изображение или любой другой элемент, на который можно нажать.
- 30 октября 2023

Как перевернуть сайт. Самая короткая инструкция
Не представляем, зачем это может понадобиться, но не могли пройти мимо.
Никакой магии. Мы вызываем JavaScript-функцию rotateBody() , которая применяет свойство transform с значением rotate(180deg) к элементу . Когда вы нажмете на кнопку «Перевернуть», всё, что находится внутри будет повернуто на 180 градусов (то есть, встанет вниз головой)
function rotateBody() < document.body.style.transform = 'rotate(180deg)'; >
Но такой код повернёт страницу только один раз. Если нужно, чтобы она возвращалась обратно при втором клике, усложним код:
let isRotated = false; function rotateBody() < if (isRotated) < document.body.style.transform = 'rotate(0deg)'; document.body.style.direction = "ltr"; >else < document.body.style.transform = 'rotate(180deg)'; document.body.style.direction = "rtl"; >isRotated = !isRotated; >
Надеемся, вы прочитали это описание до того, как нажать на кнопку.
- 25 октября 2023

Как узнать геолокацию: Geolocation API
Geolocation API позволяет сайтам запрашивать, а пользователям предоставлять свое местоположение веб-приложениям. Геолокация может использоваться для выбора города в интернет-магазине, отображения пользователя на карте или навигации в ближайший гипермаркет.
Основной метод Geolocation API — getCurrentPosition() , но есть и другие методы и свойства, которые могут пригодиться.
- 16 октября 2023

Что такое localStorage и как им пользоваться
localStorage — это место в браузере пользователя, в котором сайты могут сохранять разные данные. Это как ящик для хранения вещей, которые не исчезнут, даже если вы выключите компьютер или закроете браузер.
До localStorage разработчики часто использовали cookies, но они были не очень удобны: мало места и постоянная передача данных туда-сюда. LocalStorage появился, чтобы сделать процесс более простым и эффективным.
- 12 октября 2023

Случайное число из диапазона
Допустим, вам зачем-то нужно целое случайное число от min до max . Вот сниппет, который поможет:
function getRandomInRange(min, max)
- Math.random () генерирует случайное число между 0 и 1. Например, нам выпало число 0.54 .
- (max — min + 1): определяет количество возможных значений в заданном диапазоне. 10 — 0 + 1 = 11 . Это значит, что у нас есть 11 возможных значений (0, 1, 2, . 10).
- Math.random () * (max — min + 1): умножает случайное число на количество возможных значений: 0.54 * 11 = 5.94 .
- Math.floor (): округляет число вниз до ближайшего целого. Так, Math.floor(5.94) = 5 .
- . + min: смещает диапазон так, чтобы минимальное значение соответствовало min . Но в нашем примере, так как min = 0 , это не изменит результат. Пример: 5 + 0 = 5 .
- Итак, в нашем примере получилось случайное число 5 из диапазона от 0 до 10.
Чтобы протестировать, запустите:
console.log(getRandomInRange(1, 10)); // Тест
- 7 сентября 2023

В чём разница между var и let
Если вы недавно пишете на JavaScript, то наверняка задавались вопросом, чем отличаются var и let , и что выбрать в каждом случае. Объясняем.
var и let — это просто два способа объявить переменную. Вот так:
var x = 10; let y = 20;
Переменная, объявленная через var , доступна только внутри «своей» функции, или глобально, если она была объявлена вне функции.
function myFunction() < var z = 30; console.log(z); // 30 >myFunction(); console.log(z); // ReferenceError
Это может создавать неожиданные ситуации. Допустим, вы создаёте цикл в функции и хотите, чтобы переменная i осталась в этой функции. Если вы используете var , эта переменная «утечёт» за пределы цикла и будет доступна во всей функции.
Переменные, объявленные с помощью let доступны только в пределах блока кода, в котором они были объявлены.
if (true) < let a = 40; console.log(a); // 40 >console.log(a); // ReferenceError
В JavaScript блок кода — это участок кода, заключённый в фигурные скобки <> . Это может быть цикл, код в условном операторе или что-нибудь ещё.
if (true) < let blockScoped = "Я виден только здесь"; console.log(blockScoped); // "Я виден только здесь" >// здесь переменная blockScoped недоступна console.log(blockScoped); // ReferenceError
Если переменная j объявлена в цикле с let , она останется только в этом цикле, и попытка обратиться к ней за его пределами вызовет ошибку.
- 30 августа 2023

Быстрый гайд по if, else, else if в JavaScript
Допустим, вы собираетесь идти на прогулку. Если на улице солнечно, вы возьмёте с собой солнечные очки.
Это можно описать с помощью оператора if .
let weather = "sunny"; if (weather === "sunny")
А если погода не солнечная, а, скажем, дождливая, вы возьмете зонт.
Этот сценарий можно описать с помощью if-else .
let weather = "rainy"; if (weather === "sunny") < console.log("Возьму солнечные очки"); >else
Условный оператор if-else if-else
Теперь представим, что у вас есть несколько вариантов транспорта для дороги на работу: машина, велосипед, общественный транспорт. Выбор будет зависеть от различных условий, например, погоды и времени суток. Логично, что в дождь безопаснее ехать на автобусе, а в хорошую погоду можно прокатиться на машине или велосипеде, если утро и пробки. То есть схема такая:
И всё это очень легко описывается кодом:
let weather = "sunny"; let time = "morning"; if (weather === "rainy") < // если дождь, то только так console.log("Еду на автобусе"); >else if (time === "morning") < // если не дождь и утро console.log("Еду на велике мимо пробок"); >else < // если второе не дождь и не утро console.log("Еду на машине"); >
Ветвление только может показаться сложным, но вообще оно очень логичное, если понять, какие действия после каких условий выполняются. Разберитесь один раз и поймёте на всю жизнь, 100%.
- 30 августа 2023

Как исправить ошибки SyntaxError в JavaScript
Ошибки SyntaxError появляются, если разработчик нарушил правила синтаксиса JavaScript, например, пропустил закрывающую скобку или точку с запятой. Давайте посмотрим, что означает каждая ошибка и в чём может быть проблема.
Что означают три точки в JavaScript
Во вчерашней статье про сортировку слиянием мы использовали такой код в конце функции:
return [ . arr, . left, . right ]
Судя по квадратным скобкам, мы возвращаем массив, но в нём творится что-то странное: перед каждым элементом стоят точки, да ещё каждый из этих элементов тоже массив. Рассказываем, как такое возможно и что здесь делают три точки.
Кратко главное
- Конкретно в этом случае три точки — это оператор расширения.
- Он «разбивает» объект на набор его элементов и отдаёт их по порядку.
- Можно представить, что если объект — это набор чего-то в обёртке, то оператор расширения надрывает эту обёртку, и из объекта всё высыпается.
- Оператор можно использовать и наоборот: собрать массу каких-то значений в один объект.
Простой пример. У нас есть массив problems = [‘сессия’, ‘отчет’, ‘здоровье’] . Если просто сказать console.log(problems) , то выведется целый объект (как бы в обёртке), и работать с ним дальше нужно именно как с объектом:
❌ console.log(problems)
> (3) [‘сессия’, ‘отчет’, ‘здоровье’]
Если нам не нужен объект, а нужно просто посмотреть на значения подряд, то делаем так:
✅ console.log(. problems)
> сессия отчет здоровье
А теперь наоборот. Допустим нам нужна функция, которая разом решает все проблемы, но мы не знаем, сколько этих проблем будет. Тогда этот оператор примет любое количество значений и соберёт их в один объект:
function solve(. allProblems)
Теперь эта функция примет любое число значений и уложит их в общий массив allProblems .
Оператор расширения
Три точки в JavaScript имеют два значения: они обозначают остаточные параметры или работают как оператор расширения. В нашем примере с функцией это как раз оператор расширения, поэтому начнём с него.
Смысл оператора расширения — преобразовать объект в перечислимый список. При этом сам объект тоже должен содержать значения, которые можно посчитать и к которым можно обратиться по отдельности. Например, это может быть массив — можно перечислить по очереди всё его содержимое. Или это может быть строка — мы можем перебрать в ней каждый символ.
На практике это может работать так. Допустим, у нас есть массив с числами, и нам нужно найти наибольшее из них:
Но если мы используем обычную команду поиска максимума Math.max(a) , то ничего не выйдет: ей нужно несколько чисел, а не один большой объект:

Чтобы обойти это ограничение, используют оператор расширения — он сделает из массива отдельные значения, которые будут использоваться как параметры. В этом случае вызов команды будет выглядеть так: Math.max(. a)

Получается, что мы расширили наш объект и виртуально превратили его из единого целого в несколько отдельных значений.
Вернёмся к нашему примеру:
return [ . arr, . left, . right ]
Теперь, зная как работает оператор расширения, мы понимаем, что функция возвращает массив (потому что квадратные скобки), который собирается из трёх частей:
- Сначала в массив войдут все элементы массива arr (а не сам массив).
- Потом все элементы массива left .
- И напоследок — все элементы массива right .
Самое интересное, что если какой-то элемент окажется пустым, то от него не войдёт ничего. Вот как это работает на практике: допустим, у нас есть три массива:
- в arr будет лежать [2,7,0];
- массив left будет пустым;
- а в right — [1,2].
Тогда команда return [ . arr, . left, . right ] вернёт такой массив: [2,7,0,1,2].
Остаточные параметры
Второй способ применения трёх точек в JavaScript — использовать их как остаточный параметр. По сравнению с оператором расширения остаточный параметр работает ровно наоборот: он собирает все значения в один массив. Чтобы было проще понять, покажем на примере.
Допустим, у нас есть функция, которая складывает переданные ей параметры и возвращает сумму:
function s(a, b)
Но эта функция может работать только с двумя параметрами: если ей передать три, то она отбросит лишние и не будет их учитывать при расчётах:

А вот с помощью остаточных параметров мы можем собрать все аргументы вместе в один массив, а потом просто перебрать его и найти сумму всех значений:
function s(. args) < // тут будет храниться промежуточная сумма let sum = 0; // перебираем все элементы массива args и добавляем их к сумме for (let arg of args) sum += arg; // возвращаем сумму return sum; >console.log(s(2,4,6,8,10))

Этот приём можно использовать везде, где вы точно не знаете, сколько значений нужно будет обработать, но при этом нужно заранее предусмотреть все возможные ситуации.
Получите ИТ-профессию
В «Яндекс Практикуме» можно стать разработчиком, тестировщиком, аналитиком и менеджером цифровых продуктов. Первая часть обучения всегда бесплатная, чтобы попробовать и найти то, что вам по душе. Дальше — программы трудоустройства.
Использование .map() для итерации элементов массива в JavaScript

В JavaScript существует много разных способов и методик итерации массивов данных, от классического цикла for до метода forEach() . Метод .map() — один из самых популярных методов. Метод .map() создает массив, вызывая определенную функцию для каждого элемента родительского массива. Метод .map() не использует мутацию и создает новый массив, в отличие от мутационных методов, которые вносят изменения в вызывающий массив.
Существует много возможностей использования этого метода при работе с массивами. В этом учебном модуле мы рассмотрим четыре полезных способа использования .map() в JavaScript: вызов функции для элементов массива, конвертацию строк в массивы, рендеринг списков в библиотеках JavaScript и переформатирование элементов массива.
Предварительные требования
Для этого учебного модуля не потребуется писать код, но если вы захотите попробовать приведенные примеры, вы можете использовать Node.js REPL или инструменты для разработчика в браузере.
- Для локальной установки Node.js следуйте процедуре, описанной в документе Установка Node.js и создание локальной среды разработки.
- Инструменты Chrome DevTools можно получить, загрузив и установив последнюю версию Google Chrome.
Шаг 1 — Вызов функции для каждого элемента массива
Метод .map() принимает функцию обратного вызова как один из аргументов, и текущее значение обрабатываемого функцией элемента является важным параметром этой функции. Это обязательный параметр. С этим параметром вы можете модифицировать каждый элемент массива и создать новую функцию.
const sweetArray = [2, 3, 4, 5, 35] const sweeterArray = sweetArray.map(sweetItem => return sweetItem * 2 >) console.log(sweeterArray)
Вывод регистрируется в консоли:
Output[ 4, 6, 8, 10, 70 ]
Это можно упростить еще больше для очистки кода:
// create a function to use const makeSweeter = sweetItem => sweetItem * 2; // we have an array const sweetArray = [2, 3, 4, 5, 35]; // call the function we made. more readable const sweeterArray = sweetArray.map(makeSweeter); console.log(sweeterArray);
Этот же вывод регистрируется в консоли:
Output[ 4, 6, 8, 10, 70 ]
Использование выражений вида sweetArray.map(makeSweeter) делает код более удобочитаемым.
Шаг 2 — Конвертация строки в массив
Метод .map() принадлежит к прототипу массива. На этом шаге мы используем его для конвертации строки в массив. Здесь мы не разрабатываем метод для работы со строками. Вместо этого мы используем специальный метод .call() .
В JavaScript все элементы являются объектами, и к этим объектам прикреплены методы и функции. Метод .call() позволяет использовать контекст одного объекта с другим объектом. Поэтому вы скопируете контекст .map() в массив на строке.
Методу .call() можно передавать аргументы используемого контекста и параметры для аргументов первоначальной функции.
const name = "Sammy" const map = Array.prototype.map const newName = map.call(name, eachLetter => return `$eachLetter>a` >) console.log(newName)
Вывод регистрируется в консоли:
Здесь мы использовали контекст метода .map() на строке и им передается аргумент функции, который ожидается от метода .map() .
Такие функции как метод .split() строки, позволяют изменять только отдельные символы в строках, прежде чем возвращать их в массив.
Шаг 3 — Рендеринг списков в библиотеках JavaScript
Библиотеки JavaScript, такие как React, используют метод .map() для рендеринга элементов в списках. Однако для этого требуется синтаксис JSX, поскольку метод .map() заключен в синтаксис JSX.
Приведем пример компонента React:
import React from "react"; import ReactDOM from "react-dom"; const names = ["whale", "squid", "turtle", "coral", "starfish"]; const NamesList = () => ( div> ul>names.map(name => li key=name>> name> /li>)>/ul> /div> ); const rootElement = document.getElementById("root"); ReactDOM.render(NamesList />, rootElement);
Это компонент React без состояния, выполняющий рендеринг div со списком. Рендеринг отдельных элементов списка выполняется посредством использования метода .map() для итерации по именам, изначально созданным массивом. Рендеринг этого компонента выполняется с использованием ReactDOM на элементе DOM с Id root .
Шаг 4 — Переформатирование объектов массива
Метод .map() можно использовать для итерации объектов массива и, аналогично случаю с традиционными массивами, изменяют содержание каждого отдельного объекта и возвращают новый массив. Эта модификация выполняется на основе того, что возвращает функция обратного вызова.
const myUsers = [ name: 'shark', likes: 'ocean' >, name: 'turtle', likes: 'pond' >, name: 'otter', likes: 'fish biscuits' > ] const usersByLikes = myUsers.map(item => const container = >; container[item.name] = item.likes; container.age = item.name.length * 10; return container; >) console.log(usersByLikes);
Вывод регистрируется в консоли:
Output[ , , ]
Здесь мы модифицировали каждый объект массива, используя нотацию со скобками и точкой. Эта модель использования может применяться для обработки или конденсации полученных данных перед их сохранением или анализом в клиентском приложении.
Заключение
В этом учебном модуле мы рассмотрели четыре модели использования метода .map() в JavaScript. В сочетании с другими методами функционал метода .map() можно расширить. Дополнительную информацию можно найти в статье Использование методов массива в JavaScript: методы итерации.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
