Вступление

При изучении ценностей в javascript одна из концепций, которые люди любят или ненавидят, - это принуждение типов. Javascript очень дружелюбен к тому, чтобы знать, какой тип значения вы используете в своих выражениях и функциях. Например, вам не нужно указывать, является ли это строкой или целым числом. Однако из-за этого приведение типов может привести к тому, что ваша программа вернет значение, которого вы не ожидали при попытке выполнить код, например, сравнение значений с операторами меньше, больше или равно или даже объединение значений вместе.

Что такое приведение типов?

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

Числовые операторы

Когда мы console.log(firstVal), результат будет71.

Ну, кажется, это неправильно, не так ли?

Глядя на это, вы можете подумать, что он добавит 1 к 7 , и результат будет 8.

Это не так.

Javascript оценивает в этом выражении две вещи. Он читает “7”, который является строкой, а не числом, и он читает оператор +. Вместо этого Javascript пытается объединить строки, а не добавлять числовые значения в этом экземпляре. Это приводит к тому, что тип Javascript переводит целое число 1 в строку “1”. Итак, теперь вместо выполнения 7 + 1 он объединяет все выражение в виде строки “7” + “1” в “71”.

Мы знаем, что это правда, когда используем оператор typeof. Когда мы console.log(typeof firstVal), он сообщает нам, что результатом является строка, а не целое число.

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

В отличие от первого примера, secondVal фактически вернет нам числовое значение. Произойдет то, что “7” в выражении на этот раз будет преобразовано в числовое значение, потому что Javascript оценивает - как числовой оператор и знает, что нужно вычесть. Это выражение должно означать 7 минус 1, что дает нам 6.

Когда мы console.log( typeof secondVal), мы получаем числовой тип в консоли, а не строку, как при использовании оператора +.

Давайте посмотрим на другой способ приведения типов.

Один интересный результат, который вы можете получить из-за приведения типов, - это NaN. Давайте посмотрим, что произойдет, если вместо того, чтобы писать “7” * 1, мы выпишем “seven” * 1.

В этом случае Javascript вернет NaN, потому что он увидит * как числовой оператор умножения и попытается преобразовать “seven” в число. Когда мы console.log(typeof thirdVal), мы получаем в консоли тип number. Тем не менее, он не сможет умножить “seven” на 1. Вместо этого Javascript вернется к нам NaN, потому что Javascript пытается выяснить, какое число “seven” на самом деле оценивается. Поскольку он не может преобразовать его в действительное целое число, мы возвращаем NaN.

Что, если мы изменим выражение, чтобы оно выглядело как наш предыдущий пример с 7 в кавычках (“7” * 1)? Получим ли мы тот же результат, что и выше?

Нет, это работает успешно и возвращает нам номер. “7” в этом случае будет преобразован в числовой тип. Здесь Javascript может вернуть нам фактическое целочисленное значение, а не NaN.

После преобразования “7” в тип number fourthVal вернет 7, потому что 7, умноженное на 1, = 7.

Операторы сравнения

Если вам нужно напомнить о строгом равенстве и равенстве, ознакомьтесь с документацией MDN.

При использовании == оператор сравнения выдаст логическое значение true или false. В приведенном выше примере "7" слева будет приведен к тому же типу данных, что и другие 7, так что они станут истинными. Исключением из этого правила является NaN. Если вам интересно узнать подробности этого, я добавил правила, перечисленные в спецификации сценария ecma для Javascript.

Если Тип (x) равен String, а Type (y) - Number,
возвращает результат сравнения ToNumber ( x) == y.

Используя пример fifthVal, Number(“7”) становится целым числом 7. В данном случае 7 == 7, и это приводит к true.

Вот еще один пример:

Не вдаваясь слишком глубоко в правдивые и ложные значения для этого сообщения (ознакомьтесь с другим моим сообщением в блоге), значение false в приведенном выше выражении будет преобразовано в числовое значение для выполнения выражения. В строке 9 числовое значение false равно 0. Ноль оказывается ложным значением, поэтому 0 всегда будет истинным по сравнению с другим ложным логическим типом с использованием==.

Поскольку 0 == 0 истинно, sixthVal в строке 19 оценивается как true.

Что, если я хочу избежать принуждения к типу?

Если вы хотите избежать принуждения типов, чтобы проверить, что ваши значения точно равны, вы должны использовать строго equals===. Чтобы использовать тот же пример, что и выше, давайте изменим его на 0 === false.

Теперь Javascript больше не преобразует типы данных, и конечный результат - false вместо true.

Это потому, что 0 как числовое значение не равно false логическому значению. Вот почему для большинства логических сравнений лучше использовать строго равные. Таким образом, вы можете быть уверены в результате, основываясь на самих значениях, а не на том, как javascript меняет типы данных за вас.

Больше информации

Документация MDN

Спецификация скрипта ECMA

Правда / Ложь