Если вы наверняка работаете с JavaScript, у вас есть случай, когда вы использовали сложение (+) с числом и числовой строкой (например, «12»).
Поскольку JavaScript является языком с динамической типизацией, результат такой операции может быть (по крайней мере, в первый раз) неожиданным…

Что это означает, что JavaScript имеет динамическую типизацию?

Языки с динамической типизацией - это языки (например, JavaScript), в которых интерпретатор присваивает переменным тип во время выполнения на основе значения переменной в то время.

Https://developer.mozilla.org/en-US/docs/Glossary/Dynamic_typing

Это особенно актуально при работе с оператором сложения.

"10" + 1 // ❌"101"
1 + "10" // ❌"110"
// but...
"10" - 3 // ✅9
"12" * 3 // ✅36

Так что же здесь происходит?

Оператор сложения производит сумму числовых операндов или конкатенацию строк.

Https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Addition

Это означает, что когда хотя бы один элемент является строковым, мы концентрируем его на чем угодно, как если бы это были строки.

"1" + 2 + 3 // "123"
1 + "2" + 3 // "123"
1 + 2 + "3" // 33 ⚠️ because 1 + 2 = 3 and 3 + "3" gives us "33"
1 + 2 + "3" + 4 // 334 ⚠️ again: 1 + 2 = 3; 3 + "3" = "33"; "33" + 4 = "334"

Итак, как правильно суммировать числовые строки с числами?
Сначала нам нужно преобразовать жало в число. Есть несколько способов сделать это. Давайте погрузимся в…

Преобразовать строку в число

Метод # 1: parseInt (parseFloat)

Первый метод, самый старый, - разобрать целое число. Для этого мы используем parseInt (или parseFloat, если нам нужно число с плавающей запятой).

parseInt принимает два параметра:

  1. строка - это строка, которую мы хотим проанализировать
    ПРИМЕЧАНИЕ, если это не sting-type, она сначала преобразуется в строку
  2. radix - см. ниже документацию по параметрам MDN

Целое число от 2 до 36, которое представляет основание системы счисления (основание в математических системах счисления) string. Будьте осторожны - это не по умолчанию 10!

Https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt

Некоторые примеры parseInt

parseInt("15", 10) // 15
parseInt("15.345", 10) // 15 (we asked for integer and not float)
parseInt(15.345, 10) // 15 

Если ввод по какой-либо причине не может быть преобразован в целое число, в ответ мы получим NaN (Not-A-Number):

parseInt("Hello World", 10) // NaN

Примеры parseFloat
ПРИМЕЧАНИЕ parseFloat принимает только один параметр - значение, которое вы хотите проанализировать. Причем это должна быть строка или число.

parseFloat("15.345") // 15.345

Хорошо, но нам нужно написать битовый код для получения целого числа (или числа с плавающей запятой) из строки с помощью этих методов. Давайте посмотрим, есть ли более простые способы добиться этого ...

Метод № 2: Число ()

Number

Объект Number JavaScript - это объект-оболочка, позволяющий работать с числовыми значениями. Объект Number создается с помощью Number() конструктора. Объект примитивного типа номер создается с помощью Number() функции.

Https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number

При использовании Number в контексте, не являющемся конструктором (без оператора new), его можно использовать для выполнения преобразования типа.

Вот что мы делаем в следующих примерах:

// convert integer
Number("123") // 123
// convert floating point number
Number("3.1415") // 3.1415 
// if input can't be converted to numeric - Number returns NaN
Number("Hello World") // NaN

Красиво и чисто. Правильно? Но есть еще более короткий путь к тому же!

Способ №3. Унарный плюс (+)

Оператор унарного плюса предшествует своему операнду и оценивает его операнд, но пытается преобразовать его в число, если это еще не сделано. Хотя унарное отрицание (-) также может преобразовывать не числа, унарный плюс - это самый быстрый и предпочтительный способ преобразования чего-либо в число, поскольку он не выполняет никаких других операций с числом. Он может преобразовывать строковые представления целых чисел и чисел с плавающей запятой, а также нестроковые значения true, false и null. Поддерживаются целые числа как в десятичном, так и в шестнадцатеричном (с префиксом 0x) форматах. Поддерживаются отрицательные числа (но не шестнадцатеричные). Если он не может проанализировать конкретное значение, он будет оценивать как NaN.

Https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Unary_plus

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

См. Несколько примеров:

// converting integer
+"33" // 33
+"01234" // 1234
// float is convertible, too
+3.1415 // 3.1415
+"3.1415" // 3.1415
// converting true, false and null values
+false // 0
+true // 1
+null // 0
// converting non-numeric results in NaN (Not-A-Number)
+"Hello world" // NaN

Самый простой и кратчайший способ преобразования в целое число / число с плавающей запятой - использовать унарный оператор.

Тестирование всех методов

Давайте посмотрим, что мы можем сделать на примере, с которого начали:

"10" + 1 // ❌"101"
1 + "10" // ❌"110"

Использование parseInt / parseFloat

parseInt("10", 10) + 1 // ✅11
1 + parseInt("10", 10) // ✅11
parseFloat(10) + 1 // ✅11

Использование Number()

Number("10") + 1 // ✅11
1 + Number("10") // ✅11

Использование унарного плюса

+"10" + 1 // ✅11
1 + +"10" // ✅11

Как видите, каждый метод преобразует строковое представление числа в целое или плавающее, что позволяет нам правильно суммировать числа.

Бонус: isNaN ()

Чтобы предотвратить результат NaN при преобразовании строки в целое число / число с плавающей запятой, мы можем сначала проверить, можно ли преобразовать строковое значение в число.

Функция isNaN() определяет, равно ли значение NaN или нет.

Https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isNaN

Некоторые примеры:

isNaN("10") // false
isNaN("10.12") // false
isNaN("10.ab") // true

Вы знали все 3 метода? Какой из них вы предпочитаете? Дай мне знать - мне любопытно :)

Лично я большую часть времени использую унарный оператор. Однако, когда я делаю код, который, как я знаю, будет повторно использован другими разработчиками, я предпочитаю Number() - это более ясно о том, что он делает.