JavaScript — это язык с динамической типизацией, и поэтому периодически
бывают ситуации, когда функция возвращает значения совершенно произвольного типа.
И вы заранее — особенно если вы пользователь какой-то внешней библиотеки
— можете не знать, какой в том или ином случае будет возвращен тип значения.
Поэтому бывают ситуации, когда вам приходится сравнивать «ужа с ежом»,
то есть переменные совершенно разных типов, и как-то обрабатывать эти ситуации.
Сейчас мы рассмотрим алгоритм, по которому происходит это сравнение, и поймем,
как можно адаптировать различные типы данных,
для того чтобы они могли быть сравниваемы друг с другом.
Например, у нас есть объект панды.
У него есть метод valueOf, который возвращает код
Unicode символа с эмодзи с пандой, и у него есть метод toString,
который возвращает HTML-Entity с кодом для вставки панды в вашу HTML-страницу.
У нас есть соответственно код поросенка,
эмодзи поросенка по Unicode-таблице.
Соответственно, он просто задан примитивом целым числом.
И что будет, если мы сравним наш объект панды с числом?
Логика будет такая: будет
использоваться внутренний метод isPrimitive сначала к левому операнду.
Он будет проверять, является ли операнд примитивом.
В нашем случае — это объект, и нет, он не будет примитивом.
Далее мы вызываем этот же самый метод к правому операнду.
И в данном случае второй операнд будет примитивом.
Далее, мы проверяем
левый операнд, который не является примитивом,
имеет ли он метод valueOf и является ли этот метод функцией.
Да, в нашем случае такой метод действительно есть.
После этого он вызывает у непримитива метод valueOf и
сравнивает его с примитивом.
И по сути мы сравниваем два целых числа:
Unicode код панды, и Unicode код поросенка.
В нашем случае они неравны, поэтому сравнение объекта панды
и кода поросенка в нашем случае означает false.
Полный алгоритм вы можете найти по ссылке.
Важно понимать, что когда мы сравниваем два
объекта или два массива, вообще, два любых сложных типа данных,
которые передаются по ссылке, мы сравниваем
всегда ссылки на область памяти, в которых они находятся.
Поэтому два объекта в JavaScript, пусть и пустых, пусть и имеющих
одинаковый набор свойств, всегда будут возвращать false при их сравнении.
А теперь сравним тот же самый пример,
тот же самый объект, но уже с кодом панды в таблице Unicode.
И в данном случае мы увидим, что valueOf у панды и наш
код имеют одно и то же целое значение, и при их сравнении мы получим true.
На этом занятии мы рассмотрели основные моменты,
которые используются при сравнении переменных различных типов.
Более подробно мы в следующей лекциях рассмотрим приведение переменных к тому
или иному типу, которое происходит при их сравнении,
и в каких случаях мы приводим переменную к типу A, а в каких — к типу B.