Skip to content
Open
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
755b70a
Добавит /people/anton-fomichev
anton-fomichev Mar 10, 2025
2e0d412
Добавит черновик статьи
anton-fomichev Mar 10, 2025
6d9338e
Отредактирует статью, сократит размер до 7 минут
anton-fomichev Mar 10, 2025
0553dd8
Удалит комментарий из статьи
anton-fomichev Mar 10, 2025
a55f864
Отредактирует статью, расставит акценты
anton-fomichev Mar 10, 2025
f056adb
Изменит description
anton-fomichev Mar 10, 2025
6d09904
Уберет упоминание объектов, добавит секцию "Приведение к числу"
anton-fomichev Mar 13, 2025
1907f5d
Добавит скрытую секцию "Как работают операторы по спецификации ECMASc…
anton-fomichev Mar 13, 2025
eeec9d9
Пофиксит стиль написания
anton-fomichev Mar 14, 2025
53a55db
Переместит "Как работают операторы по спецификации ECMAScript"
anton-fomichev Mar 14, 2025
f8e9e88
Покажет на примере, как `+` работает по спеке ECMAScript
anton-fomichev Mar 15, 2025
53425ad
Перепишет "Как выполнение операторов описывает спецификация ECMAScript"
anton-fomichev Mar 16, 2025
c563822
Объединит секции внутри "Не только математика"
anton-fomichev Mar 16, 2025
b62530a
Добавляет доку в индекс JS
vitya-ne Mar 17, 2025
a29b48e
Ставит точку в дискришине
vitya-ne Mar 17, 2025
f3008a9
Добавит "related" и удалит "keywords"
anton-fomichev Mar 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
320 changes: 320 additions & 0 deletions js/operators/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,320 @@
---
title: "Базовые операторы в JS"
description: "Обзор ключевых операторов JavaScript: арифметика, приоритет, инкремент и декремент, присваивание"
authors:
- anton-fomichev
keywords:
-
related:
-
tags:
- doka
---

## Кратко

В JavaScript есть несколько базовых операторов, с которыми разработчики сталкиваются постоянно в ходе своей работы. Они позволяют выполнять арифметические действия, изменять значения переменных, а также помогают разработчику упростить некоторые операции в коде.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Может быть, второе слово "разработчик" убрать? мне кажется, по контексту понятно, что речь идёт о разработчике.


## Кто такие: «оператор», «операнд»?

- **Оператор** — символ (или ключевое слово), говорящий движку, какую операцию совершить

- **Операнд** — это то, над чем оператор выполняет действие (например: число, строка, переменная)

## Типы операторов

### Унарные операторы

Унарные операторы зависят от одного операнда. Другими словами, они действуют только на один объект.

Пример — _унарный минус_ `-`:

```js
let x = 5
console.log(-x)
// -5
```

### Бинарные операторы

Бинарные операторы применяются к двум операндам.

Например, оператор `+` применяется к операндам `x` и `y`:

```js
const x = 5, y = 2
console.log(x + y)
// 7
```

Рассмотрим другой пример: оператор `>` сравнивает числа и возвращает значение логического типа:

```js
const user = { age: 19 }
console.log(user.age > 18)
// true
```

## Математика

JavaScript поддерживает стандартные арифметические операторы, которые помогают складывать, вычитать, умножать и делить числа. Ниже перечислены самые популярные из них:

### Сложение, вычитание, умножение и деление

```js
console.log(10 + 3)
// 13
console.log(10 - 3)
// 7
console.log(10 * 3)
// 30
console.log(10 / 3)
// 3.3333...
console.log(10 - 'blablabla')
// NaN
```

### Остаток от деления

```js
console.log(10 % 3)
// 1
console.log(8 % 2)
// 0
```

### Возведение в степень

```js
console.log(2 ** 2)
// 4
console.log(2 ** 5)
// 32
```

## Не только математика

JavaScript позволяет применять операторы не только к числам — на практике можно встретить ситуации, когда один или оба операнда оказываются строками, булевыми значениями или даже объектами.

<details>
<summary>Как JavaScript обрабатывает оператор <code>+</code> по спецификации ECMAScript</summary>

Рассмотрим принцип работы операции [ApplyStringOrNumericBinaryOperator()](https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-applystringornumericbinaryoperator) на примере оператора `+`:

**1. Приведение к примитивам**
Оба операнда последовательно приводятся к примитивам с помощью [ToPrimitive()](https://tc39.es/ecma262/multipage/abstract-operations.html#sec-toprimitive).

**2. Проверка на строку**
Если хотя бы один из операндов — строка, то второй операнд будет приведён к строке и результатом операции будет конкатенация:

```js
console.log(5 + '2')
// '52'
```

В противном случае операция рассматривается как арифметическая.

**3. Приведение к Number или BigInt**
JavaScript применяет [ToNumeric()](https://tc39.es/ecma262/multipage/abstract-operations.html#sec-tonumeric) к обоим операндам.

**4. Проверка на несовместимость**
Если один операнд оказался Number, а другой — BigInt, будет выброшена ошибка TypeError:

```js
42n + 1 // TypeError: Cannot mix BigInt and other types, use explicit conversions
```

**5. Арифметические действия**
Если оба операнда — Number, используется [Number::add](https://tc39.es/ecma262/multipage/ecmascript-data-types-and-values.html#sec-numeric-types-number-add). Если оба операнда оказываются BigInt, вызывается [BigInt::add](https://tc39.es/ecma262/multipage/ecmascript-data-types-and-values.html#sec-numeric-types-bigint-add):

```js
console.log(2 + 3)
// 5
console.log(2n + 3n)
// 5n
```

</details>

### Конкатенация строк

Если хотя бы один операнд у оператора `+` — строка, в результате получится склейка (конкатенация). Например:

```js
console.log('Hello' + ' ' + 'world')
// 'Hello world'
console.log('5' + 2)
// '52'
```

### Сравнение строк

Операторы сравнения, такие как `>` или `<`, могут применяться к строкам. При этом строки сравниваются _лексикографически_ — посимвольно в порядке символов, а не по их «числовому» содержанию.

Следующее выражение возвращает `true` после сравнения первых символов строк `'2'` и `'15'` — `'2'` и `'1'`:

```js
console.log('2' > '15')
// true
```

Каждому символу соответствует код из [UTF-16](https://ru.wikipedia.org/wiki/UTF-16), с помощью которого и происходит сравнение двух символов.

### Приведение к числу

Во время выполнения арифметических операций JavaScript пытается преобразовать операнды к числу.

Например, при использовании оператора `-` со строкой:

```js
let x = '10'
console.log(x - 1)
// 9, строка '10' привелась к числу 10
```

Также существует унарный плюс `+`, который явно превращает строку в число:

```js
console.log(+'42')
// 42
```

Подробнее о том, как JavaScript преобразует строки, объекты и другие типы данных, можно посмотреть в статье [преобразование типов](/js/typecasting/).

### Преобразование объектов

При попытке использовать арифметические операторы вроде `+`, `-` или `*` с объектами или массивами, JavaScript попытается привести их к примитиву через метод `toString()` или `valueOf()`. Иногда это приводит к результатам, которые сложно предсказать, если не знать механизма преобразований:

```js
console.log({} + {})
// '[object Object][object Object]'

// В массиве по умолчанию toString() склеивает элементы:
console.log([1, 2, 3] + [4, 5])
// '1,2,34,5'
```

### Булевые значения

В арифметическом контексте `true` приводится к `1`, а `false` — к `0`. Однако при конкатенации строк (`+`) булевые значения не будут автоматически превращаться в числа:

```js
console.log(true + 1)
// 2
console.log(false + 10)
// 10
console.log(true + '1')
// 'true1'
```

## Приоритет операторов

В JavaScript у операторов есть определённый порядок выполнения. Это означает, что некоторые операции будут выполняться раньше других, если в выражении нет дополнительных скобок.

Приоритет _унарных_ операторов выше, чем приоритет _бинарных_ (за некоторыми исключениями: оператор группировки, вызов функции, доступ к свойствам и т. п.). Подробнее можно посмотреть в [таблице приоритетов](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Operators/Operator_precedence#таблица).

На практике запоминать приоритет всех операторов не нужно: в спорных случаях всегда лучше проставить скобки явно.

### Присваивание

Оператор присваивания `=` в JavaScript находится почти в самом низу приоритетов. Его суть проста: взять значение выражения справа и присвоить переменной слева. Например:

```js
const result = 10
```

Важно, что оператор присваивания возвращает значение, которое было присвоено переменной:

```js
let a
console.log(a = 'Hello world!')
// 'Hello world!'
```

Оператор присваивания выполняется справа налево. В примере ниже, сначала выполнится `b = 5`, вернётся `5`, а затем значение присвоится `a`. В итоге `a` и `b` оба станут равны `5`:

```js
let a, b
console.log(a = b = 5)
// 5
console.log(a, b)
// 5 5
```

#### Как делать не надо

Иногда можно увидеть слишком хитрые конструкции, где в одном выражении смешиваются разные операторы, в том числе присваивания. Например:

```js
const a = 2 + (b = 3 * 5) // a = 17, b = 15
```

Такой код работает, но его сложно читать и поддерживать, особенно если в нём участвуют более сложные вычисления. В большинстве случаев лучше разбить логику на несколько строк — так понятнее и надёжнее:

```js
const b = 3 * 5 // 15
const a = 2 + b // 17
```

### Инкрементное присваивание

Помимо обычного оператора `=`, в JavaScript есть целая группа _сокращённых операторов присваивания_. Они позволяют одновременно выполнить арифметическую операцию и присвоить результат переменной. Например:

- `x += 1` эквивалентно `x = x + 1`;
- `x -= 2` эквивалентно `x = x - 2`;
- `x *= 3` эквивалентно `x = x* 3`;
- `x /= 4` эквивалентно `x = x / 4`;
- `x %= 5` эквивалентно `x = x % 5`;
- `x **= 6` эквивалентно `x = x ** 6`.

Зачем это нужно?

1. **Короткая запись**. Вместо `x = x + 10` можно использовать `x += 10`;
1. **Удобство при изменении счётчика**. В циклах или при пошаговом изменении переменной такие записи упрощают код и делают его немного выразительнее.

## Инкремент и декремент

Инкремент и декремент — это унарные операторы, которые увеличивают или уменьшают значение переменной на `1`. Выглядят они так:

- **Инкремент**: `++`,
- **Декремент**: `--`.

При этом существует две формы — _префиксная_ и _постфиксная_. Они отличаются моментом, когда переменная меняет своё значение.

### Постфиксная форма

Постфиксные операторы (`x++`, `x--`) сначала **возвращают старое значение**, а лишь затем меняют переменную:

```js
let x = 5
console.log(x++)
// 5 (возвращаем старое значение)
console.log(x)
// 6 (теперь переменная увеличена)
```

### Префиксная форма

Префиксные операторы (`++x`, `--x`) сначала изменяют переменную, а затем **возвращают новое значение**:

```js
let count = 5
console.log(++count)
// 6 (значение уже увеличено)
console.log(count)
// 6 (значение остаётся увеличенным)
```

### Когда использовать

Инкремент и декремент нередко применяют в циклах `for` или `while`, чтобы удобнее управлять переменными-счётчиками. Вывод чисел от 0 до 4 (включительно) в консоль может выглядеть так:

```js
for (let i = 0; i < 5; i++) {
console.log(i)
}
```

### Подводные камни

Чаще всего проблемы в использовании инкремента или декремента в JavaScript связаны с особенностями постфиксной или префиксной формы. Если не помните, когда возвращается старое значение, а когда новое, лучше используйте отдельные инструкции присваивания.
7 changes: 7 additions & 0 deletions people/anton-fomichev/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
name: 'Антон Фомичев'
url: https://github.com/anton-fomichev
photo: photo.jpeg
---

Разрабатываю и оптимизирую фронтенд с 2021 года. Уделяю особое внимание UX. Для меня важно не стоять на месте: экспериментирую с технологиями, делюсь знаниями в open source сообществе 🤝
Binary file added people/anton-fomichev/photo.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading