Отличия == и === в JavaScript
В JavaScript есть два похожих оператора: == и ===. Если не знать их отличия, это может обернуться кучей ошибок. Так что решил раскрыть эту тему. Чем именно отличаются == и ===, как они работают, почему так происходит, и как избежать ошибок.
Оператор == сравнивает на равенство, а вот === — на идентичность. Плюс оператора === состоит в том, что он не приводит два значения к одному типу. Именно из-за этого он обычно и используется.
abc == undefined; // true, если abc = undefined | null abc === undefined; // true - только если abc = undefined!
abc == false; // true, если abc = false | 0 | '' | [] abc === false; // true, только если abc = false!
Ведь путать false и 0 (или », или []) — вряд ли очень хорошо.
5 === 5; // true true === true; // true 'abc' === 'abc'; // true
А теперь интересный пример.
5 == 5; // true 5 === 5; // true new Number(5) == 5; // true new Number(5) === 5; // false!
Почему так происходит? Да, любое число — это объект класса Number. Но можно представить число как цифру — некоторой константой. Она единожды объявлена, и всегда идентична сама себе. Но в то же время объявляя новый объект класса Number — он равен ей по значению, но не идентичен (так как это два совершенно разных объекта класса Number).
Arrays / Objects
А вот для массивов и объектов оба оператора работают одинаково, сравнивая на идентичность:
var a = <>; a == <>; // false a === <>; // false a == a; // true a === a; // true
Для сравнения массивов и объектов можно написать специальную функцию:
function isEq(a, b) < if(a == b) return true; for(var i in a)< if(!isEq(a[i], b[i])) return false; >for(var i in b) < if(!isEq(a[i], b[i])) return false; >return true; >
Немножко неаккуратно, два цикла, да и про hasOwnProperty забыли; ну да сойдёт.
This
Есть ещё один подводный камень. Это передача в this.
(function()< this == 5; // true this === 5; // false >).call(5);
(function()< this == 5; // true this === 5; // false >).call(5);Вот такой вот момент. Стоит о нём не забывать.
Итого.
Ну а теперь представим, что мы пишем свой суперфреймворк, активно юзаем там оператор === вместо == просто потому что он красивее, и некто находит у нас несколько багов.
func(new Number(5)); (function()< func(this); >).call(5);
Кажется, что такие примеры нежизнеспособны? Пожалуйста!
$.each([1, 2, 3, 4, 5], function()< func(this); >);
Ну или захотелось расширить цифру.
var Five = new Number(5); Five.a = 2; // захотелось расширить, а просто 5 не расширяется // здесь как-то используем. func(Five);
На этом всё, надеюсь кому-то будет полезно. Спасибо за внимание.
UPD. Спасибо за ссылку vermilion1, JS Гарден.
- равенство
- идентичность
В чем разница между == и ===?
@VladD Да, мне тоже любопытно. Много специалистов JavaScript, например Douglas Crockford, считают, что это было ошибка. Кажется, что дизайнер JavaScript, как и дизайнеры PHP, думал что будет легче для программистов если язык преобразывает типы автоматическим образом. А мне кажется наоборот, что надо про типы думать больше, когда неожиданно преобразываются.
4 июл 2015 в 15:41
А сие точно не дубль?
14 сен 2016 в 14:43
@nick_n_a, это скорее оригинал 🙂
14 сен 2016 в 14:43
ассоциация: stackoverflow.com/q/359494/14227417
21 дек 2020 в 14:11
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
Операторы === и !== являются операторами строгого сравнения. Значит, если операнды имеют разные типы, то не являются равными. Например:
1 === "1" // возвращает false 1 !== "1" // возвращает true null === undefined // возвращает false
Операторы == и != являются операторами, скажем, грубого сравнения. То есть, если операнды имеют разные типы, JavaScript пытается как-то преобразовать их, чтобы стали сравнимыми. Например:
1 == "1" // возвращает true 1 != "1" // возвращает false null == undefined // возвращает true
Интересно заметить, что в отличие от === , оператор == не является транзитивным:
"0" == 0 // true 0 == "" // true "0" == ""// false
Не очень легко помнить правила этого грубого сравнения, и иногда бывает, что оно работает неожиданным образом. Поэтому, я рекомендую использовать === вместо == .
Даже я не помню мелкие детали оператора == , так что посмотрим в спецификации, пункт 11.9.3:
Алгоритм сравнения абстрактного равенства
- Если Type(x) такой же, что и Type(y), то
- Если Type(x) – Undefined, вернуть true.
- Если Type(x) – Null, вернуть true.
- Если Type(x) – Number, то
- Если x – NaN, вернуть false.
- Если y – NaN, вернуть false.
- Если x имеет такое же числовое значение, что и y, вернуть true.
- Если x равно +0 и y равно −0, вернуть true.
- Если x равно −0 и y равно +0, вернуть true.
- Вернуть false.
Логические операторы. Объясните мне, в чем разница?


& — Логическое AND (И) && — Сокращённое AND | — Логическое OR (ИЛИ) || — Сокращённое OR ^ — Логическое XOR (исключающее OR (ИЛИ)) ! — Логическое унарное NOT (НЕ) &= — AND с присваиванием |= — OR с присваиванием ^= — XOR с присваиванием == — Равно != — Не равно ?: — Тернарный (троичный) условный оператор оператор Мне, как новичку большинство из них понятны, а те что не понятны можно погуглить. Но гугл мне не ответил, в чем разница между логическим И (ИЛИ) и сокращенным? В чем принципиальное отличие (если оно есть). В каких случаях можно применить тот или иной оператор? Спасибо.
Разница между операторами >>> и >>
В Java есть два вида операторов сдвига вправо: >>> и >> . Они используются для сдвига битового представления числа вправо.
Оператор сдвига >>
Оператор >> (сдвиг вправо) сдвигает биты числа вправо на указанное количество позиций. Важно отметить, что при этом знак числа сохраняется, т.е. если было отрицательное число, то и после сдвига оно останется отрицательным.
int a = -10; a = a >> 2; // результат будет -3
Оператор сдвига >>>
Оператор >>> (беззнаковый сдвиг вправо) также сдвигает биты числа вправо на указанное количество позиций, но при этом знак числа всегда становится положительным, т.е. старший бит (знаковый) устанавливается в 0.
int a = -10; a = a >>> 2; // результат будет 1073741821
Вывод
Важно отличие между операторами >> и >>> заключается в том, как они обрабатывают старший (знаковый) бит. >> сохраняет значение старшего бита, тем самым сохраняя знак числа, в то время как >>> устанавливает старший бит в 0, делая число положительным.