Вступление
При изучении ценностей в 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 меняет типы данных за вас.