Какой оператор равен (== vs ===) должен использоваться в сравнении JavaScript?

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

Есть ли преимущество в производительности для замены == на ===?

Любые улучшения производительности будут приветствоваться, поскольку существует множество операторов сравнения.

Если преобразование типа не происходит, будет ли коэффициент усиления по сравнению с ==?

Ответ 1

Оператор тождества (===) ведет себя идентично оператору равенства (==), за исключением того, что преобразование типов не выполняется, и типы должны быть одинаковыми, чтобы считаться равными.

Ссылка: Учебник по Javascript: Операторы сравнения

Оператор == будет сравнивать на равенство после выполнения любых необходимых преобразований типов. Оператор === не будет выполнять преобразование, поэтому, если два значения не одного типа, === просто вернет false. Оба одинаково быстры.

По словам Дугласа Крокфорда, отличный JavaScript: хорошие части,

В JavaScript есть два набора операторов равенства: === и !==, и их злые близнецы == и !=. Хорошие работают так, как вы ожидаете. Если два операнда имеют один и тот же тип и имеют одинаковое значение, то === выдает true а !== выдает false. Злые близнецы поступают правильно, когда операнды относятся к одному и тому же типу, но если они относятся к разным типам, они пытаются привести значения. правила, по которым они это делают, сложны и не запоминаются. Вот некоторые из интересных случаев:

'' == '0'           // false
0 == ''             // true
0 == '0'            // true

false == 'false'    // false
false == '0'        // true

false == undefined  // false
false == null       // false
null == undefined   // true

' \t\r\n ' == 0     // true

Отсутствие транзитивности вызывает тревогу. Мой совет - никогда не использовать злых близнецов. Вместо этого всегда используйте === и !==. Все только что показанные сравнения дают false с оператором ===.


Обновить:

Хороший момент был воспитан @Casebash в комментариях и в @Phillipe Laybaert в ответ относительно ссылочных типов. Для ссылочных типов == и === действуют согласованно друг с другом (кроме как в особом случае).

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

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

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

a == b            // false
a === b           // false

c == d            // false
c === d           // false

e == f            // true
e === f           // true

Особый случай - когда вы сравниваете литерал с объектом, который оценивает один и тот же литерал из-за его метода toString или valueOf. Например, рассмотрим сравнение строкового литерала со строковым объектом, созданным конструктором String.

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

Здесь оператор == проверяет значения двух объектов и возвращает true, но === видит, что они не одного типа, и возвращает false. Который правильный? Это действительно зависит от того, что вы пытаетесь сравнить. Мой совет - полностью обойти вопрос и просто не использовать конструктор String для создания строковых объектов.

Ссылка
http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3

Ответ 2

Использование оператора == (Равенство)

true == 1; //true, because 'true' is converted to 1 and then compared
"2" == 2;  //true, because "2" is converted to 2 and then compared

Использование оператора === (личность)

true === 1; //false
"2" === 2;  //false

Это связано с тем, что оператор равенства == выполняет приведение типов, что означает, что интерпретатор неявно пытается преобразовать значения перед сравнением.

С другой стороны, оператор тождества === не выполняет приведение типов и, следовательно, не преобразует значения при сравнении и поэтому работает быстрее (как в соответствии с этим тестом JS), поскольку пропускает один шаг.

Ответ 3

Интересное графическое представление сравнения равенства между == и ===.

Источник: http://dorey.github.io/JavaScript-Equality-Table/


var1 === var2

При использовании === для тестирования равенства JavaScript все как есть. Перед оценкой ничего не преобразуется.

Equality evaluation of === in JS


var1 == var2

При использовании == для тестирования равенства JavaScript используются некоторые смешные конверсии.

Equality evaluation of == in JS

Мораль истории:

Используйте === если вы не полностью понимаете конверсии, которые происходят с ==.

Ответ 4

В ответах здесь я ничего не читал о том, что означает equal. Некоторые скажут, что === означает равный и одного и того же типа, но это не так. Фактически это означает, что оба операнда ссылаются на один и тот же объект или в случае типов значений имеют то же значение.

Итак, давайте возьмем следующий код:

var a = [1,2,3];
var b = [1,2,3];
var c = a;

var ab_eq = (a === b); // false (even though a and b are the same type)
var ac_eq = (a === c); // true

То же самое и здесь:

var a = { x: 1, y: 2 };
var b = { x: 1, y: 2 };
var c = a;

var ab_eq = (a === b); // false (even though a and b are the same type)
var ac_eq = (a === c); // true

Или даже:

var a = { };
var b = { };
var c = a;

var ab_eq = (a === b); // false (even though a and b are the same type)
var ac_eq = (a === c); // true

Такое поведение не всегда очевидно. Там больше к истории, чем к тому, чтобы быть равным и быть того же типа.

Правило:

Для типов значений (числа):
 a === b возвращает true, если a и b имеют одинаковое значение и имеют один и тот же тип

Для ссылочных типов:
 a === b возвращает true, если a и b ссылаются на один и тот же объект

Для строк:
 a === b возвращает true, если a и b являются обеими строками и содержат одинаковые символы


Строки: специальный случай...

Строки не являются типами значений, но в Javascript они ведут себя как типы значений, поэтому они будут "равны", когда символы в строке одинаковы и когда они имеют одинаковую длину (как объяснено в третьем правиле)

Теперь становится интересно:

var a = "12" + "3";
var b = "123";

alert(a === b); // returns true, because strings behave like value types

Но как насчет этого?:

var a = new String("123");
var b = "123";

alert(a === b); // returns false !! (but they are equal and of the same type)

Я думал, что строки ведут себя как типы значений? Ну, это зависит от того, кого вы спросите... В этом случае a и b не являются одним и тем же типом. a имеет тип Object, а b имеет тип string. Просто помните, что создание строкового объекта с использованием конструктора string создает нечто вроде типа Object, которое большую часть времени ведет себя как строка.

Ответ 5

Позвольте мне добавить этот совет:

Если есть сомнения, прочтите спецификацию!

ECMA-262 - это спецификация языка сценариев, на котором JavaScript является диалектом. Конечно, на практике важно, как ведут себя самые важные браузеры, чем эзотерическое определение того, как что-то должно обрабатываться. Но полезно понять, почему новый String ( "a" )! == "a" .

Пожалуйста, дайте мне пояснить, как прочитать спецификацию, чтобы прояснить этот вопрос. Я вижу, что в этой очень старой теме никто не получил ответа за очень странный эффект. Итак, если вы можете прочитать спецификацию, это очень поможет вам в вашей профессии. Это приобретенное умение. Итак, продолжайте.

Поиск файла PDF для === приводит меня на страницу 56 спецификации: 11.9.4. Оператор Strict Equals (===), и после прохождения через спецификацию я нахожу:

11.9.6 Алгоритм сравнения строгого равенства
Сравнение x === y, где x и y - значения, создает true или false. Такое сравнение выполняется следующим образом:
  1. Если Type (x) отличается от Type (y), верните false.
  2. Если тип (x) равен Undefined, верните true.
  3. Если Type (x) - Null, верните true.
  4. Если Type (x) не является числом, перейдите к шагу 11.
  5. Если x NaN, верните false.
  6. Если y NaN, верните false.
  7. Если x - это то же числовое значение, что и y, верните true.
  8. Если x равно +0, а y равно -0, верните true.
  9. Если x равно -0 и y равно +0, верните true.
  10. Вернуть false.
  11. Если Type (x) - String, верните true, если x и y - это точно такая же последовательность символов (одинаковая длина и одинаковые символы в соответствующих позициях); в противном случае верните false.
  12. Если Type (x) является логическим, верните true, если x и y оба true или оба false; в противном случае верните false.
  13. Верните true, если x и y относятся к одному и тому же объекту или относятся к объектам, связанным друг с другом (см. 13.1.2). В противном случае верните false.

Интересным является этап 11. Да, строки рассматриваются как типы значений. Но это не объясняет, почему новый String ( "a" )! == "a" . У нас есть браузер, не соответствующий ECMA-262?

Не так быстро!

Проверить типы операндов. Попробуйте сами, обернув их в typeof(). Я обнаружил, что новый String ( "a" ) является объектом, а используется шаг 1: return false, если типы отличаются.

Если вам интересно, почему новый String ( "a" ) не возвращает строку, как насчет некоторых упражнений, читающих спецификацию? Получайте удовольствие!


Aidiakapi написал это в комментарии ниже:

Из спецификации

11.2.2 Новый оператор:

Если тип (конструктор) не является объектом, вызовите исключение TypeError.

Другими словами, если String не будет иметь тип Object, он не может использоваться с новым оператором.

new всегда возвращает объект, даже для конструкторов Строка. И увы! Семантика значения для строк (см. Шаг 11) теряется.

И это, наконец, означает: новый String ( "a" )! == "a" .

Ответ 6

В PHP и JavaScript это строгий оператор равенства. Это означает, что он будет сравнивать тип и значения.

Ответ 7

Я тестировал это в Firefox с помощью Firebug, используя следующий код:

console.time("testEquality");
var n = 0;
while(true) {
    n++;
    if(n==100000) 
        break;
}
console.timeEnd("testEquality");

и

console.time("testTypeEquality");
var n = 0;
while(true) {
    n++;
    if(n===100000) 
        break;
}
console.timeEnd("testTypeEquality");

Мои результаты (проверены пять раз и усреднены):

==: 115.2
===: 114.4

Итак, я бы сказал, что незначительная разница (это более 100000 итераций, помните) пренебрежимо мала. Производительность не является причиной ===. Тип безопасности (ну, как безопасно, как вы собираетесь в JavaScript), и качество кода.

Ответ 8

В JavaScript это означает одно и то же значение и тип.

Например,

4 == "4" // will return true

но

4 === "4" // will return false 

Ответ 9

Оператор === называется оператором строгого сравнения, он отличается от оператора ==.

Возьмем 2 vars a и b.

Для "a == b" для оценки истины a и b должно быть одно значение.

В случае "a === b" a и b должны быть одинаковое значение, а также того же типа для него для оценки истины.

Возьмем следующий пример

var a = 1;
var b = "1";

if (a == b) //evaluates to true as a and b are both 1
{
    alert("a == b");
}

if (a === b) //evaluates to false as a is not the same type as b
{
    alert("a === b");
}

В заключение; использование оператора == может оцениваться как истинное в ситуациях, когда вы этого не хотите, поэтому использование оператора === будет более безопасным.

В сценарии использования 90% не имеет значения, какой из них вы используете, но полезно знать разницу, когда вы получаете какое-то неожиданное поведение в один прекрасный день.

Ответ 10

Он проверяет, равны ли одинаковые стороны как по типу, так и по значению.

Пример:

'1' === 1 // will return "false" because 'string' is not a 'number'

Общий пример:

0 == ''  // will be "true", but it very common to want this check to be "false"

Другой распространенный пример:

null == undefined // returns "true", but in most cases a distinction is necessary

Ответ 11

Почему == настолько непредсказуем?

Что вы получаете, когда сравниваете пустую строку "" с номером 0 0?

<код > Trueкод >

Да, это правильно в соответствии с == пустая строка, а числовое ноль - одно и то же время.

И это не заканчивается, вот еще один:

  '0' == false//true
Код>

Вещи становятся очень странными с массивами.

  [1] == true//true
[] == false//true
[[]] == false//true
[0] == false//true
Код>

Затем weerder со строками

  [1,2,3] == '1,2,3'//true - ДЕЙСТВИТЕЛЬНО?!
'\ r\n\t' == 0//true - Давай!
Код>

Ухудшается:

Когда равно не равно?

  let A = ''//пустая строка
пусть В = 0//нуль
пусть C = '0'//нулевая строка

A == B//true - ok...
B == C//true - пока что так хорошо...
A == C//** FALSE ** - Закручивание сюжета!
Код>

Позвольте мне еще раз сказать:

  (A == B) && & & (B == C)//true
(A == C)//** FALSE **
Код>

И это просто сумасшедший материал, который вы получаете с примитивами.

Это новый уровень безумия, когда вы используете == с объектами.

В этот момент вам, наверное, интересно...

Почему это происходит?

Хорошо, потому что в отличие от "тройного равенства" ( ===), который просто проверяет, совпадают ли два значения.

== делает целую кучу других вещей.

Он имеет специальную обработку для функций, специальную обработку для нулей, undefined, строк, которые вы называете.

Это становится довольно дурацким.

На самом деле, если вы попытались написать функцию, которая делает то, что делает ==, она будет выглядеть примерно так:

  function isEqual (x, y) {//если `==` были функцией   if (typeof y === typeof x) return y === x;   // обрабатываем null и undefined то же самое   var xIsNothing = (y === undefined) || (y === null);   var yIsNothing = (x === undefined) || (x === null);
   если (xIsNothing || yIsNothing) возвращается (xIsNothing & yIsNothing);
   if (typeof y ===  "function"  || typeof x ===  "function" ) {       // если любое значение является строкой       // преобразовать функцию в строку и сравнить       if (typeof x ===  "string" ) {           return x === y.toString();       } else if (typeof y ===  "string" ) {           return x.toString() === y;       }       return false;   }
   if (typeof x ===  "object" ) x = toPrimitive (x);   if (typeof y ===  "object" ) y = toPrimitive (y);   if (typeof y === typeof x) return y === x;
   // конвертируем x и y в числа, если они еще не используют трюк +   if (typeof x! ==  "number" ) x = + x;   if (typeof y! ==  "number" ) y = + y;   // фактически реальный `==` еще более сложный, чем это, особенно в ES6   return x === y;
}

функция toPrimitive (obj) {   var value = obj.valueOf();   if (obj! == value) возвращаемое значение;   return obj.toString();
}
Код>

Итак, что это значит?

Это означает, что == является сложным.

Поскольку это сложно, трудно понять, что произойдет, когда вы его используете.

Это означает, что у вас могут быть ошибки.

Итак, мораль этой истории...

Сделайте вашу жизнь менее сложной.

Используйте === вместо ==.

Конец.

Ответ 12

Схема последовательности выполнения Javascript для строгого равенства/Сравнение '==='

Javascript строгое равенство

Схема выполнения выполнения Javascript для нестандартного равенства/сравнения '=='

Javascript non равенство

Ответ 13

JavaScript === vs ==.

0==false   // true
0===false  // false, because they are of a different type
1=="1"     // true, auto type coercion
1==="1"    // false, because they are of a different type

Ответ 14

Это означает равенство без принуждения типа тип принуждения означает, что JavaScript не автоматически конвертирует любые другие типы данных в строковые типы данных.

0==false   // true,although they are different types

0===false  // false,as they are different types

2=='2'    //true,different types,one is string and another is integer but 
            javaScript convert 2 to string by using == operator 

2==='2'  //false because by using === operator ,javaScript do not convert 
           integer to string 

2===2   //true because both have same value and same types 

Ответ 15

В типичном script не будет разницы в производительности. Более важным может быть тот факт, что тысяча "===" составляет 1 килобайт тяжелее, чем тысячи "==":) профилировщики JavaScript, может сказать вам, есть ли производительность разница в вашем случае.

Но лично я бы сделал то, что предлагает JSLint. Эта рекомендация существует не из-за проблем с производительностью, а из-за ограничения типа ('\t\r\n' == 0).

Ответ 16

Оператор равного сравнения == запутан, и его следует избегать.

Если вы живете с ИМЕЕТЕ, помните следующие 3 вещи:

  • Он не является транзитивным: (a == b) и (b == c) не приводит к (a == c)
  • Он взаимно исключает его отрицание: (a == b) и (a!= b) всегда имеют противоположные булевы значения со всеми a и b.
  • В случае сомнений выучите наизусть следующую таблицу истинности:

ТАБЛИЦА ПРАВИЛЬНОГО ОПЕРАТОРА В JAVASCRIPT

  • Каждая строка в таблице представляет собой набор из 3 взаимно "равных" значений, что означает, что любые 2 значения из них равны с использованием знака равного == *

** STRANGE: обратите внимание, что любые два значения в первом столбце не равны в этом смысле. **

''       == 0 == false   // Any two values among these 3 ones are equal with the == operator
'0'      == 0 == false   // Also a set of 3 equal values, note that only 0 and false are repeated
'\t'     == 0 == false   // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
'\r'     == 0 == false   // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
'\n'     == 0 == false   // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
'\t\r\n' == 0 == false   // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

null == undefined  // These two "default" values are not-equal to any of the listed values above
NaN                // NaN is not equal to any thing, even to itself.

Ответ 17

Вряд ли будет какая-либо разница в производительности между двумя операциями в вашем использовании. Нет никакого преобразования типа, которое должно быть выполнено, потому что оба параметра уже одного типа. Обе операции будут иметь сравнение типов, за которыми следует сравнение значений.

Ответ 18

Да! Это имеет значение.

=== оператор в javascript проверяет значение, а также тип, где оператор == просто проверяет значение (при необходимости преобразовывает тип).

enter image description here

Вы можете легко протестировать его. Вставьте следующий код в файл HTML и откройте его в браузере

<script>

function onPageLoad()
{
    var x = "5";
    var y = 5;
    alert(x === 5);
};

</script>

</head>

<body onload='onPageLoad();'>

В предупреждении вы получите " false". Теперь измените метод onPageLoad() на alert(x == 5);, вы получите true.

Ответ 19

Оператор

=== проверяет значения, а также типы переменных для равенства.

Оператор

== просто проверяет значение переменных для равенства.

Ответ 20

Это строгий контрольный тест.

Это хорошо, особенно если вы проверяете между 0 и false и null.

Например, если у вас есть:

$a = 0;

Тогда:

$a==0; 
$a==NULL;
$a==false;

Все возвращает true, и вы можете не хотеть этого. Предположим, что у вас есть функция, которая может вернуть 0-й индекс массива или false при ошибке. Если вы установите флажок с "==" false, вы можете получить запутанный результат.

Итак, с тем же, что и выше, но строгий тест:

$a = 0;

$a===0; // returns true
$a===NULL; // returns false
$a===false; // returns false

Ответ 21

JSLint иногда дает нереалистичные причины для изменения материала. === имеет ту же производительность, что и ==, если типы уже совпадают.

Это быстрее, только если типы не совпадают, и в этом случае он не пытается конвертировать типы, но возвращает false.

Итак, IMHO, JSLint, возможно, используется для написания нового кода, но бесполезную чрезмерную оптимизацию следует избегать любой ценой.

Смысл, нет никаких причин для изменения == до === в тесте, например if (a == 'test'), когда вы это знаете, поскольку факт может быть только String.

Модификация большого количества кода таким образом отнимает время разработчиков и рецензентов и ничего не достигает.

Ответ 22

Просто

== означает сравнение между операндами с type conversion

&

=== означает сравнение между операндами без type conversion

Преобразование типов в javaScript означает, что javaScript автоматически преобразует любые другие типы данных в строковые типы данных.

Например:

123=='123'   //will return true, because JS convert integer 123 to string '123'
             //as we used '==' operator 

123==='123' //will return false, because JS do not convert integer 123 to string 
            //'123' as we used '===' operator 

Ответ 23

Простым примером является

2 == '2'  -> true, values are SAME because of type conversion.

2 === '2'  -> false, values are NOT SAME because of no type conversion.

Ответ 24

Как правило, я бы использовал === вместо ==!== вместо !=).

Причины объяснены в ответах выше, и Дуглас Крокфорд довольно ясно об этом (JavaScript: Хорошие части).

Однако есть одно единственное исключение: == null - эффективный способ проверить наличие 'null или undefined':

if( value == null ){
    // value is either null or undefined
}

Например, jQuery 1.9.1 использует этот шаблон 43 раза, и по этой причине программа проверки синтаксиса JSHint даже предоставляет eqnull.

Из руководства по стилю jQuery:

Строгие проверки на равенство (===) должны использоваться в пользу ==. Единственное исключение - при проверке неопределенности и нуля посредством нуля.

// Check for both undefined and null values, for some important reason. 
undefOrNull == null;

Ответ 25

Топ-2 ответов на оба упомянутых == означает равенство и === означает идентификатор. К сожалению, это утверждение неверно.

Если оба операнда из == являются объектами, то их сравнивают, чтобы увидеть, являются ли они одним и тем же объектом. Если оба операнда указывают на один и тот же объект, то оператор равенства возвращает true. В противном случае, они не равны.

var a = [1, 2, 3];  
var b = [1, 2, 3];  
console.log(a == b)  // false  
console.log(a === b) // false  

В приведенном выше коде оба == и === получают false, потому что a и b не являются одними и теми же объектами.

Чтобы сказать: если оба операнда из == являются объектами, == ведет себя так же, как ===, что также означает идентификацию. Существенным отличием этих двух операторов является преобразование типов. == имеет преобразование, прежде чем он проверит равенство, но === не делает.

Ответ 26

Проблема в том, что вы можете легко попасть в неприятности, поскольку JavaScript имеет много неявных преобразований, смысл...

var x = 0;
var isTrue = x == null;
var isFalse = x === null;

Которая довольно скоро становится проблемой. Лучший пример того, почему неявное преобразование является "злым", можно извлечь из этого кода в MFC/С++, который будет скомпилирован из-за неявного преобразования из CString to HANDLE, который является типом typedef указателя...

CString x;
delete x;

Что явно во время выполнения делает очень undefined вещи...

Google для неявных преобразований в С++ и STL, чтобы получить некоторые аргументы против него...

Ответ 27

В базовая ссылка javascript

=== Возвращает true, если операнды строго равны (см. выше) без преобразования типа.

Ответ 28

Сравнение равенства:

Оператор ==

Возвращает true, когда оба операнда равны. Перед сопоставлением операнды преобразуются в один тип.

>>> 1 == 1
true
>>> 1 == 2
false
>>> 1 == '1'
true

Сравнение уровней и типов:

Оператор ===

Возвращает true, если оба операнда равны и одного типа. Это вообще лучше и безопаснее, если вы сравните этот путь, потому что нет конверсий типа "за кадром".

>>> 1 === '1'
false
>>> 1 === 1
true

Ответ 29

* Операторы === vs == *

1 == true    =>    true
true == true    =>    true
1 === true    =>    false
true === true    =>    true

Ответ 30

Вот удобная таблица сравнения, в которой показаны преобразования, которые происходят, и различия между == и ===.

Как говорится в заключении:

"Используйте три равных, если вы не полностью понимаете, какие конверсии место для двух равных".

http://dorey.github.io/JavaScript-Equality-Table/