В JavaScript, если вы работаете с массивами или объектами, вы можете столкнуться с чем-то странным. Если у вас есть два одинаковых массива или объекта и вы попытаетесь проверить, одинаковы ли они, вы получите «false».
[1, 2, 3] === [1, 2, 3]; //Returns "false" [1, 2, 3] == [1, 2, 3]; //Returns "false" let object1 = {make: "Ford", model: "F150", color: "white"}; let object2 = {make: "Ford", model: "F150", color: "white"}; object1 === object2; //Returns "false" object1 == object 2; //Returns "false"
Это может показаться бессмысленным, особенно если учесть следующее:
object1 = object2; object1 === object2; //Returns "true"
Если бы вы проверяли эквивалентность со многими другими типами данных, вы всегда получали бы истину. Единственные типы данных, которые имеют эту проблему, — это NaN, массивы, объекты и функции (даже если возвращаемое значение функций одинаково).
Это связано с тем, что строки, числа, нулевые значения, неопределенные значения и логические значения являются примитивными, а большинство других (кроме NaN) — нет.
Примечание. Проблема NaN != NaN немного сложнее. Но о том, что я думаю об этом, я расскажу позже.
Вместо того, чтобы вдаваться в то, как JavaScript ссылается на значения, я бы предпочел обсудить, как я думаю об этой проблеме, чтобы, возможно, помочь кому-то новому (например, мне) осмыслить разницу.
Скажем, мы описываем двух однояйцевых близнецов. Можно сказать, что у них обоих карие глаза, черные волосы и обувь 12-го размера. Ведь они идентичны. Записав их как объекты, мы можем иметь:
const tom = {hair: "black", eyes: "brown", shoeSize: 12}; const jerry = {hair: "black", eyes: "brown", shoeSize: 12};
Том и Джерри не один и тот же человек, но
tom.hair === jerry.hair; //Returns "true" tom.eyes === jerry.eyes; //Returns "true" tom.shoeSize === jerry.shoeSize; //Returns "true" tom === jerry; //Returns "false"
Черные волосы — это черные волосы, карие глаза — это карие глаза, а размер 12 футов — это размер 12 футов, независимо от того, на ком они одеты.
Если однажды Джерри решит покрасить волосы в фиолетовый цвет, то это описание изменится, но не повлияет на Тома. Тогда у Тома не будет фиолетовых волос, и он останется Томом, на которого решение Джерри совершенно не повлияет.
И это оставляет NaN. Что случилось с NaN?
Ну, NaN может быть чем угодно и не говорит вам, что это такое. Он просто говорит вам, что это не число.
Если бы я сказал вам, что у меня нет рыжих волос и что у моего соседа тоже нет рыжих волос, у вас все равно не было бы информации о том, какого цвета у нас волосы. У вас недостаточно информации, чтобы решить, действительно ли у нас волосы одного цвета или нет, поэтому вы не можете вернуть «правда» без дополнительной информации. Вот крайний пример:
const notANumber = 0/0; notANumber; //Returns NaN notANumber === notANumber; //Returns "false"
Мы знаем, что 0/0 — это не число. Это то, что сохраняет компьютер, и это единственное, что мы о нем знаем.
Чем это отличается от «null» или «undefined»?
Для нулевых значений ничто — это то же самое, что и ничто. Нет никакой разницы между тем, что я ничего не держу в правой руке, и тем, что я ничего не держу в левой руке. Вы не можете различить их, если вы не философ или ученый, а компьютеры ни то, ни другое.
Неопределенные значения — это просто слова, которые не были определены. Слова «jellyflops» и «squimblegloop» — это слова, но неопределенные. У них точно такое же значение (отсутствие смысла), поэтому они функционально идентичны.