Доброго времени суток.
В 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);
На этом всё, надеюсь кому-то будет полезно. Спасибо за внимание.