Вот вам код на JavaScript. Если его исполнить, результат будет 9. Это нелогично для нас, но совершенно понятно, логично и предсказуемо с точки зрения JavaScript. Вот почему.
Разбираемся, что лежит в скобках
В JavaScript прямые скобки — это признак того, что перед нами массив. Когда мы объявляем новый массив, то обычно делаем это так:
var arr = [1,2,3,4,5];
Слева у нас переменная, в которую мы отправляем новое значение, а справа — массив, который мы хотим поместить в переменную. Получается, что мы можем просто объявить массив в квадратных скобках, а значит, вот что у нас лежит в этих массивах:
[1] — здесь лежит нечто, похожее на 1
[2] — здесь — похожее на 2
[3] — а здесь — на 3
Здесь всё неопределённо, потому что мы явно не указывали тип данных. По этой причине JavaScript относится к таким данным настороженно и считает их максимально аккуратно.
Теперь сложим первые два массива.
Складываем первые два массива и смотрим на результат
Так как JavaScript выполняет все действия так, как это принято в математике, то сначала он сложит первые два массива между собой.
Проблема здесь в том, что JavaScript в момент вычисления не знает, что конкретно мы имели в виду под числами в этих массивах — числа, строки или что-то ещё. Единственный безопасный способ для JavaScript сложить что-то неизвестное — привести всё к строкам и сложить уже их.
Значит, в момент вычисления [1] + [2] мы по факту получим такое:
"1" + "2", но так как строки при сложении просто соединяются, то в результате будет строка "12":
Вычитаем третий массив
JavaScript может складывать друг с другом почти что угодно (через строки и общие типы), но с вычитанием гораздо строже: для вычитания нужны числа. Это значит, что перед тем, как вычитать из одного другое, JavaScript сделает два промежуточных действия:
- Переведёт строку "12" в число и получит просто 12. Если бы перевод не удался, код бы сразу выдал ошибку приведения типов.
- Точно так же переведёт [3] в число и получит число 3.
Теперь наши вычисления превратились в простое математическое действие:
12 − 3 = 9
Вот так и выходит, что по отдельности в массивах лежит что-то, похожее на числа, но вместе получаются то строки, то снова числа.
Короче
Когда JavaScript видит плюс, он может интерпретировать его и как «сложение», и как «склеивание» в зависимости от того, какие данные перед ним. Если в данных какая-то каша, JavaScript их скорее склеит, чем сложит.
Минус — это однозначное вычитание и требует только чисел, поэтому JavaScript постарается преобразовать всё в числа.