Pull to refresh

Отличия == и === в JavaScript

JavaScript *
Sandbox
Сразу предупрежу, да, статья немного некорректная, добро пожаловать в комментарии, там неплохие уточнения ).

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


В 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 Гарден.
Tags: равенствоидентичность
Hubs: JavaScript
Total votes 107: ↑61 and ↓46 +15
Comments 68
Comments Comments 68