Сразу предупрежу, да, статья немного некорректная, добро пожаловать в комментарии, там неплохие уточнения ).
В JavaScript есть два похожих оператора: == и ===. Если не знать их отличия, это может обернуться кучей ошибок. Так что решил раскрыть эту тему. Чем именно отличаются == и ===, как они работают, почему так происходит, и как избежать ошибок.
Оператор == сравнивает на равенство, а вот === — на идентичность. Плюс оператора === состоит в том, что он не приводит два значения к одному типу. Именно из-за этого он обычно и используется.
Ведь путать false и 0 (или '', или []) — вряд ли очень хорошо.
Разумеется:
А теперь интересный пример.
Почему так происходит? Да, любое число — это объект класса Number. Но можно представить число как цифру — некоторой константой. Она единожды объявлена, и всегда идентична сама себе. Но в то же время объявляя новый объект класса Number — он равен ей по значению, но не идентичен (так как это два совершенно разных объекта класса Number).
А вот для массивов и объектов оба оператора работают одинаково, сравнивая на идентичность:
Для сравнения массивов и объектов можно написать специальную функцию:
Немножко неаккуратно, два цикла, да и про hasOwnProperty забыли; ну да сойдёт.
Есть ещё один подводный камень. Это передача в this.
Вот такой вот момент. Стоит о нём не забывать.
Ну а теперь представим, что мы пишем свой суперфреймворк, активно юзаем там оператор === вместо == просто потому что он красивее, и некто находит у нас несколько багов.
Кажется, что такие примеры нежизнеспособны? Пожалуйста!
jQuery:
Ну или захотелось расширить цифру.
На этом всё, надеюсь кому-то будет полезно. Спасибо за внимание.
UPD. Спасибо за ссылку vermilion1, JS Гарден.
Доброго времени суток.
В 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);
Вот такой вот момент. Стоит о нём не забывать.
Итого...
Ну а теперь представим, что мы пишем свой суперфреймворк, активно юзаем там оператор === вместо == просто потому что он красивее, и некто находит у нас несколько багов.
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);
На этом всё, надеюсь кому-то будет полезно. Спасибо за внимание.
UPD. Спасибо за ссылку vermilion1, JS Гарден.