JavaScript / [Из песочницы] Отличия == и === в JavaScript

в 15:23, , рубрики: равенство, метки:

Доброго времени суток.

В JavaScript есть два похожих оператора: == и ===. Если не знать их отличия, это может обернуться кучей ошибок. Так что решил полностью раскрыть эту тему. Чем именно отличаются == и ===, как они работают, почему так происходит, и как избежать ошибок.
Оператор == сравнивает на равенство, а вот === — на идентичность. Плюс оператора === состоит в том, что он не приводит два значения к одному типу. Именно из-за этого он обычно и используется.

abc == undefined; // true, если abc = undefined | null | 0 | false | '' | а также [] в IE6
abc === undefined; // true - только если abc = undefined!

Потому это часто используют в функциях, проверяя аргумент на существование, когда значение аргумента может равняться 0, false или пустой строке.
А теперь интересный пример.
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);

Вот такой вот момент. Стоит о нём не забывать.
Итого...

Ну а теперь представим, что мы пишем свой суперфреймворк, активно юзаем там оператор === вместо == просто потому что он красивее, и некто находит у нас несколько багов.
func(new Number(5));
(function(){
func(this);
}).call(5);

Кажется, что такие примеры нежизнеспособны? Пожалуйста!
jQuery:
$.each([1, 2, 3, 4, 5], function(){
func(this);
});

Ну или захотелось расширить цифру.
var Five = new Number(5);
Five.a = 2; // захотелось расширить, а просто 5 не расширяется
// здесь как-то используем...
func(Five);

На этом всё, надеюсь кому-то будет полезно. Спасибо за внимание.


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js