Сразу предупрежу, да, статья немного некорректная, добро пожаловать в комментарии, там неплохие уточнения ).
В 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 Гарден.
