JavaScript. === или == (имеет ли значение, какой оператор использовать)?

JavaScript, Вопросы и ответы
20 февраля 2012

Вопрос

Я использую JSLint для проверки своего JavaScript, и он выдаёт огромное количество советов касательно замены == на === (когда дело касается сравнений типа idSele_UNVEHtype.value.length==0 внутри оператора if). Я не думаю, что после замены я получу хоть какой-то выигрыш в производительности. Хотя кто знает, ведь этих операторов сотни, если не тысячи во всех моих файлах.

Я пробовал найти какую-то информацию по поводу производительности в поиске, но запросы типа “=== против ==”, похоже, не очень хорошо воспринимаются поисковыми системами. Что Вы мне подскажите по этому поводу?


Ответ №1

Оператор идентичности “===” ведёт себя так же, как и оператор равенства “==”, за исключением того, что он не выполняет преобразование типов. Если 2 значения имеют разный тип, оператор === сразу возвращает “false”, и в этом случае он будет работать действительно быстрее. Во всех других случаях производительность будет одинаковая.

Но стоит учитывать одну важную особенность: эти операторы могут вернуть разный результат при сравнении операндов разных типов. Неожиданным может отказаться результат работы == (который ещё называют «зловещие близнецы» - «evil twins»), ведь при получении операндов разных типов он будет пытаться преобразовать их, а уж затем сравнивать. Плавила, по которым проходит такое преобразование, довольно запутаны и сложны для запоминания. Есть несколько классических примеров работы «зловещих близнецов»:

alert( '' == '0' );           // false
alert( 0 == '' );             // true
alert( 0 == '0' );            // true

alert( false == 'false' );    // false
alert( false == '0' );        // true

alert( false == undefined );  // false
alert( false == null );       // false
alert( null == undefined );   // true

alert( ' \t\r\n ' == 0 );     // true

Разница между ожиданиями и реальность просто разительная, особенно для начинающего программиста. Мой совет - никогда не используйте сравнение равенства, лучше используйте сравнения идентичности “===” и “!==”.

Однако, для ссылочных типов данных работа обеих операторов сопоставима:

var a = [1,2,3];
var b = [1,2,3];
// a == b            false
// a === b           false

var c = { x: 1, y: 2 };
var d = { x: 1, y: 2 };
// c == d            false
// c === d           false

var e = "text";
var f = "te" + "xt";
// e == f            true
// e === f           true

Но при использовании “===” тоже надо быть внимательным и учитывать следующий особый случай. Если Вы сравните строковую переменную с объектом типа String с тем же значением, Вы получите:

alert( "abc" == new String("abc") );     // true
alert( "abc" === new String("abc") );    // false

Здесь оператор “==” сравнивает значения двух объектов, и после приведения к единому типу возвращает “true”, но оператор “===” сразу видит, что типы разные, и возвращает “false”. Нельзя сказать, что последний поступает не верно или не логично. Просто такова особенность идентичного равенства в JavaScript, и с ней надо считаться. Мой совет, чтобы обойти эту проблему стороной, просто не используйте конструктор String для создания строк.

Нет комментариев

Добавить комментарий


(обязательно)