Один из наиболее частых вопросов на собеседовании, с которым сталкивается каждый разработчик JavaScript в своей карьере: «В чем разница между ==
и ===
?» Что ж, я думаю, большинство из читающих это уже подумали с наиболее частым ответом, который
‘’ == ’’ сравнивает значение, а «===» сравнивает значение и тип.
Что, если я скажу, что это неправильный ответ 🙈. Давайте углубимся и разберемся, что происходит за кулисами. Согласно спецификациям сценария ECMA, как ==
, так и ===
проверяют тип переменных. Если типы совпадают, и ==
, и ===
работают с одним и тем же постом, который они возвращают true
или false
в зависимости от значений. Это когда типы переменных не совпадают, оба различаются. 😳
Когда типы не совпадают, ==
выполняет неявное приведение, а ===
напрямую возвращает false
. Неявное принуждение - это не что иное, как преобразование переменной из одного типа в другой.
Согласно спецификации ECMAScript, всякий раз, когда JavaScript встречает оператор ==
, вызывается абстрактная операция с именем IsLooselyEqual ( x, y )
. Точно так же, когда он встречает оператор ===
, выполняется абстрактная операция с именем IsStrictlyEqual ( x, y )
. Я понимаю, что на данный момент это может быть слишком много, чтобы переварить, но давайте попробуем разобраться в обеих этих операциях с помощью некоторых фрагментов кода. Мы не будем рассматривать все случаи операции, скорее мы попытаемся рассмотреть некоторые из распространенных сценариев, с которыми мы обычно сталкиваемся.
Дело 1:
var stringOne = '1'; var numberOne = 1; if (stringOne == numberOne) { console.log("IsLooselyEqual(x,y) is invoked"); }
В приведенном выше фрагменте кода у нас есть две переменные -stringOne
и numberOne
типов string
и number
соответственно. После этого у нас есть условный оператор, в котором мы проверяем, равны ли stringOne
и numberOne
, используя оператор ==
. Как только JavaScript встречает оператор ==
, он применяет абстрактную операцию IsLooselyEqual(x,y)
. В соответствии с этой операцией выполняются следующие шаги.
- Он проверяет, совпадают ли типы
stringOne
иnumberOne
. Если они одинаковы, он возвращает значение, применяя абстрактную операциюIsStrictlyEqual(x, y)
(Шаг 2 фактического алгоритма), гдеx
будетstringOne
иy
будетnumberOne
соответственно. - Если типы не совпадают, он проверяет, является ли тип
stringOne
типомString
, а типомnumberOne
Number
типом (Шаг 6 фактического алгоритма). Поскольку это правда, он преобразуетstringOne
переменную вNumber
тип, применяя абстрактную операциюToNumber(x)
.ToNumber(x)
- еще одна абстрактная операция, которая преобразует переменную вNumber Type
. В этом сценарииstringOne
будетx
, применениеToNumber(x)
операции будетToNumber(stringOne)
, гдеstringOne
будет преобразовано из типаString
в типNumber
на основе this. После чего он возвращает значение, снова применяяIsLooselyEqual(x, y)
абстрактную операцию, где теперь иx
, иy
имеют один и тот же тип. - Поскольку оба они одного типа, он возвращает значение, применяя абстрактную операцию
IsStrictlyEqual(x,y)
. IsStrictlyEqual(x,y)
проверяет, совпадают ли типыx
иy
. Если типы совпадают, он проверяет значение какx
, так иy
. Если значения также совпадают, тогда операция вернетtrue
, иначе она вернетfalse
.
Случай 2:
var arrayOne = ['1']; var numberOne = 1; if (arrayOne == numberOne) { console.log("IsLooselyEqual(x,y) is invoked"); }
В приведенном выше фрагменте кода у нас есть две переменные arrayOne
и numberOne
типов object
и number
соответственно. После этого у нас есть условный оператор, в котором мы проверяем, равны ли arrayOne
и numberOne
, используя оператор ==
. Как только JavaScript встречает оператор ==
, он применяет абстрактную операцию IsLooselyEqual(x,y)
. В соответствии с этой операцией выполняются следующие шаги.
- Он проверяет, совпадают ли типы
arrayOne
иnumberOne
. Если они одинаковы, он возвращает значение, применяяIsStrictlyEqual(x, y)
абстрактную операцию, гдеx
будетarrayOne
иy
будетnumberOne
соответственно. - Если типы не совпадают, он проверяет, является ли тип
arrayOne
типомObject
, а типомnumberOne
String, Number etc
типом (Шаг 12 фактического алгоритма). Поскольку это правда, он преобразует переменную типаObject
в типPrimitive
, применяя абстрактную операциюToPrimitive()
. Вкратце, эта операция пытается преобразовать типObject
в типPrimitive
, который будет либо типомString
, либоNumber
(ToPrimitive). - Затем он возвращает значение, применяя операцию
IsLooselyEqual(x, y)
, передаваяx
иy
, и повторяет те же шаги до тех пор, пока типыx
иy
не станут равными или когда операцияIsLooselyEqual(x, y)
вернетfalse
.
Случай 3:
var objectOne = []; var booleanOne = true; if(objectOne) { console.log("This check whether array is empty or not won't work !!") }
В приведенном выше фрагменте кода у нас есть две переменные objectOne
и booleanOne
типов object
и boolean
соответственно. После этого у нас есть условный оператор, в котором мы проверяем, является ли objectOne
true
. Как только JavaScript обнаруживает это, он применяет новую абстрактную операцию под названием ToBoolean(x)
. Эта операция преобразует переменную в тип Boolean
в зависимости от справочной таблицы в этом (ToBoolean).
На основе этой таблицы, поскольку наша переменная имеет тип Object
, она вернет нам true
независимо от того, пуст массив или нет. Это основная причина, по которой нам нужны другие параметры при сравнении Object
типов. В нашем случае, поскольку мы четко знаем, что это объект массива, мы могли бы использовать свойство length
. Теперь мы можем реорганизовать приведенный выше код следующим образом для проверки пустоты.
К настоящему времени я надеюсь, что вы поняли, как JavaScript обрабатывает операторы ==
и ===
и случаи, когда они на самом деле различны. Вышеупомянутое - лишь несколько сценариев из многих. Если вам действительно интересно копнуть глубже, я бы порекомендовал вам ознакомиться с Спецификациями ECMA, где вы найдете полную реализацию как IsLooselyEqual(x,y)
, так и IsStrictlyEqual(x,y)
абстрактных операций. Я также рекомендую вам прочитать эту книгу, если вы еще этого не сделали - You Don't Know JS от Kyle Simpson.
Спасибо
Надеюсь, вам понравилось это чтение об операторах ==
и ===
и о том, как работают сравнения в JavaScript. Теперь вы можете использовать эти знания, чтобы по-настоящему ответить на поставленный выше вопрос в ваших предстоящих интервью 😜. Сообщите мне свои мысли в разделе комментариев ниже. Если вы считаете, что эта статья полезна, пожалуйста, проявите свою любовь и поделитесь этим со своими собратьями, которые могут извлечь из этого максимум пользы.
Всегда свободно связывайтесь со мной через Twitter, LinkedIn или электронную почту. Рад помочь всеми возможными способами. 😊
Пока мы не встретимся снова, The Mallu Dev подписывает контракт 👋 Ура! 🥂
Больше контента на plainenglish.io