[1] + [2] - [3] = 9. Да как так-то?
medium

[1] + [2] - [3] = 9. Да как так-то?

Объясняем, как работает JavaScript

Вот вам код на JavaScript. Если его исполнить, результат будет 9. Это нелогично для нас, но совершенно понятно, логично и предсказуемо с точки зрения JavaScript. Вот почему.

[1] + [2] - [3] = 9. Да как так-то?

Разбираемся, что лежит в скобках

В JavaScript прямые скобки — это признак того, что перед нами массив. Когда мы объявляем новый массив, то обычно делаем это так:

var arr = [1,2,3,4,5];

Слева у нас переменная, в которую мы отправляем новое значение, а справа — массив, который мы хотим поместить в переменную. Получается, что мы можем просто объявить массив в квадратных скобках, а значит, вот что у нас лежит в этих массивах:

[1] — здесь лежит нечто, похожее на 1

[2] — здесь — похожее на 2

[3] — а здесь — на 3

Здесь всё неопределённо, потому что мы явно не указывали тип данных. По этой причине JavaScript относится к таким данным настороженно и считает их максимально аккуратно.

Теперь сложим первые два массива.

Складываем первые два массива и смотрим на результат

Так как JavaScript выполняет все действия так, как это принято в математике, то сначала он сложит первые два массива между собой.

Проблема здесь в том, что JavaScript в момент вычисления не знает, что конкретно мы имели в виду под числами в этих массивах — числа, строки или что-то ещё. Единственный безопасный способ для JavaScript сложить что-то неизвестное — привести всё к строкам и сложить уже их. 

Значит, в момент вычисления [1] + [2] мы по факту получим такое:

"1" + "2", но так как строки при сложении просто соединяются, то в результате будет строка "12":

[1] + [2] - [3] = 9. Да как так-то?

Вычитаем третий массив

JavaScript может складывать друг с другом почти что угодно (через строки и общие типы), но с вычитанием гораздо строже: для вычитания нужны числа. Это значит, что перед тем, как вычитать из одного другое, JavaScript сделает два промежуточных действия:

  1. Переведёт строку "12" в число и получит просто 12. Если бы перевод не удался, код бы сразу выдал ошибку приведения типов.
  2. Точно так же переведёт [3] в число и получит число 3.

Теперь наши вычисления превратились в простое математическое действие: 

12 − 3 = 9

Вот так и выходит, что по отдельности в массивах лежит что-то, похожее на числа, но вместе получаются то строки, то снова числа.

Короче

Когда JavaScript видит плюс, он может интерпретировать его и как «сложение», и как «склеивание» в зависимости от того, какие данные перед ним. Если в данных какая-то каша, JavaScript их скорее склеит, чем сложит. 

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

JavaScript — это фронтенд
На новом курсе «Практикума» о фронтенде вас обучат самым востребованным технологиям: JS и TypeScript, Flexbox и Grid, React, Git, Bash и др. Это то, что нужно работодателям сегодня. Старт — бесплатно.
Начать бесплатно
JavaScript — это фронтенд JavaScript — это фронтенд JavaScript — это фронтенд JavaScript — это фронтенд
Получите ИТ-профессию
В «Яндекс Практикуме» можно стать разработчиком, тестировщиком, аналитиком и менеджером цифровых продуктов. Первая часть обучения всегда бесплатная, чтобы попробовать и найти то, что вам по душе. Дальше — программы трудоустройства.
Начать карьеру в ИТ
Получите ИТ-профессию Получите ИТ-профессию Получите ИТ-профессию Получите ИТ-профессию
Еще по теме
medium