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

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

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

любое улучшение представления было бы приветствовано по мере того как много операторов сравнения существуют.

если преобразование типов не происходит, будет ли прирост производительности над ==?

30 ответов


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

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

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

процитировать Дугласа Крокфорда отлично JavaScript: Хорошие Части,

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

'' == '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 в комментариях и в @Филипп 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. Какой из них правильный? Это зависит от того, что вы пытаетесь сравнить. Мой совет-полностью обойти вопрос и просто не использовать the String конструктор для создания строковых объектов.

Reference
http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3


С помощью == оператор (равенство)

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

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

С другой стороны,оператор удостоверение === не делает тип принуждения, и таким образом не преобразует значения при сравнивающий.


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

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

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 с помощью String конструктор создает что-то типа Object что ведет себя как строка большая часть время.


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

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


var1 === var2

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

Equality evaluation of === in JS


var1 == var2

при использовании == для тестирования равенства JavaScript, некоторые фанки преобразования происходят.

Equality evaluation of == in JS

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

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


позвольте мне добавить такой совет:

если вы сомневаетесь, прочитайте спецификация!

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

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

Поиск PDF-файла для === приводит меня к странице 56 спецификации:11.9.4. Оператор Строгого Равенства ( = = = ), и после пробираться через specificationalese I найти:

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

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

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

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

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


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

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

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

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

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

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

и это, наконец, означает: новая строка ("a")!= = "а".


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


Я проверил это в Firefox с Палий используя такой код:

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), и качество кода.


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

например,

4 == "4" // will return true

но

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

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

давайте возьмем 2 vars a и b.

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

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

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

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");
}

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

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


он проверяет, равны ли одинаковые стороны в тип а также стоимостью.

пример:

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

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

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

еще один распространенный пример:

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

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

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

true

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

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

'0' == false // true

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

[1] == true // true
[] == false // true
[[]] == false // true
[0] == false // true

тогда странно со строки

[1,2,3] == '1,2,3' // true - REALLY?!
'\r\n\t' == 0 // true - Come on!

что хуже:

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

let A = ''  // empty string
let B = 0   // zero
let C = '0' // zero string

A == B // true - ok... 
B == C // true - so far so good...
A == C // **FALSE** - Plot twist!

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

(A == B) && (B == C) // true
(A == C) // **FALSE**

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

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

на данный момент, наверное ваш удивляющийся...

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

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

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

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

это сделать довольно дурацкие.

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

function isEqual(x, y) { // if `==` were a function
    if(typeof y === typeof x) return y === x;
    // treat null and undefined the same
    var xIsNothing = (y === undefined) || (y === null);
    var yIsNothing = (x === undefined) || (x === null);

    if(xIsNothing || yIsNothing) return (xIsNothing && yIsNothing);

    if(typeof y === "function" || typeof x === "function") {
        // if either value is a string 
        // convert the function into a string and compare
        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;

    // convert x and y into numbers if they are not already use the "+" trick
    if(typeof x !== "number") x = +x;
    if(typeof y !== "number") y = +y;
    // actually the real `==` is even more complicated than this, especially in ES6
    return x === y;
}

function toPrimitive(obj) {
    var value = obj.valueOf();
    if(obj !== value) return value;
    return obj.toString();
}

что это значит?

значит == сложная.

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

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

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

использовать === вместо ==.

Конец.


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

Javascript strict equality

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

Javascript non equality


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

значит равенство без принуждения принуждение типа означает, что 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 

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

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


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

Если вы ДОЛЖНЫ жить с этим, а затем помнить следующие 3 вещи:

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

РАВНАЯ ТАБЛИЦА ИСТИННОСТИ ОПЕРАТОРА В 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.

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


да! это действительно важно.

=== оператор в 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); вы get правда.


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

== оператор просто проверяет значение переменной на равенство.


Это строгая проверка.

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

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

$a = 0;

затем:

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

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

Так же, как и выше, но a строгий тест:

$a = 0;

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

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

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

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

значение, нет причин изменить == to === в чеке, как if (a == 'test') когда вы знаете, что A может быть только строкой.

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


просто

== означает сравнение между операндами С 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 

простой пример

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

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

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

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

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

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

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


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

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

здесь одно-единственное исключение: == null - это эффективный способ проверить для null или undefined':
if( value == null ){
    // value is either null or undefined
}

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

С руководство по стилю jQuery:

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

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

С core javascript reference

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


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

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

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

CString x;
delete x;

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

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


равенство сравнения:

оператор ==

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

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

равенство и сравнение типов:

оператор ===

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

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

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

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

null и undefined-это ничто, то есть

var a;
var b = null;

здесь a и b не имеют значения. Тогда как 0, false и " - все значения. Кое-что общее между всеми этими, что они все ложь, что означает, что они все удовлетворить условия ложь.

Итак, 0, false и " вместе образуют подгруппу. С другой стороны, null & undefined образуют вторую подгруппу. Проверьте сравнения на рисунке ниже. null и undefined было бы равно. Остальные трое будут равны друг другу. Но все они рассматриваются как ложные условия в JavaScript.

Enter image description here

Это то же самое, что и любой объект (например, {}, массивы и т. д.), непустая строка и логическое значение true - все условия истинности. Но не все они равны.