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

javascript operators equality equality-operator identity-operator

1696782 просмотра

30 ответа

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

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

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

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

Автор: bcasp Источник Размещён: 22.10.2019 02:40

Ответы (30)


6301 плюса

Решение

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

Ссылка: Учебник по 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

Автор: Bill the Lizard Размещён: 11.12.2008 02:25

1102 плюса

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

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 ), поскольку пропускает один шаг.

Автор: Andreas Grech Размещён: 11.12.2008 02:33

678 плюса

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

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


var1 === var2

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

Оценка равенства === в JS


var1 == var2

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

Оценка равенства == в JS

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

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

Автор: SNag Размещён: 05.05.2014 05:21

603 плюса

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

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

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

Автор: Philippe Leybaert Размещён: 05.06.2009 07:11

264 плюса

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

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

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

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

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

11.9.6 Алгоритм
сравнения строгого равенства Сравнение x === y, где x и y - значения, дает истину или ложь . Такое сравнение выполняется следующим образом:
  1. Если Type (x) отличается от Type (y), вернуть false .
  2. Если Тип (x) не определен, верните true .
  3. Если Тип (x) равен Null, вернуть true .
  4. Если тип (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. Вернуть ложь .
  11. Если Type (x) - String, тогда вернуть true, если x и y - это абсолютно одинаковая последовательность символов (одинаковая длина и одинаковые символы в соответствующих позициях); в противном случае верните false .
  12. Если Type (x) - логическое значение, вернуть true, если x и y оба - true или оба false ; в противном случае верните false .
  13. Верните истинуесли x и y ссылаются на один и тот же объект или если они ссылаются на объекты, соединенные друг с другом (см. 13.1.2). В противном случае верните false .

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

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

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

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


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

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

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

Если Type (конструктор) не является Object, генерировать исключение TypeError.

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

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

И это, наконец, означает: новая строка («а»)! == «а» .

Автор: nalply Размещён: 28.11.2009 06:18

101 плюса

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

Автор: Shiki Размещён: 12.05.2010 12:58

96 плюса

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

Автор: Simon Scarfe Размещён: 25.12.2008 11:17

94 плюса

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

Например,

4 == "4" // will return true

но

4 === "4" // will return false 
Автор: Dimitar Размещён: 12.05.2010 12:58

84 плюса

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

Давайте возьмем 2 переменные a и b.

Чтобы "a == b" было оценено как истинное, 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% не имеет значения, какой из них вы используете, но удобно знать разницу, когда вы однажды получите неожиданное поведение.

Автор: Reinstate Monica Размещён: 11.12.2008 02:58

78 плюса

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

Пример:

'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
Автор: vsync Размещён: 12.05.2010 12:58

75 плюса

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

Что вы получаете, когда сравниваете пустую строку ""с нулевым числом 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**

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

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

На данный момент ваш, вероятно, интересно ...

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

Что ж, это потому, что в отличие от «triple equals» ( ===), который просто проверяет, совпадают ли два значения.

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

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

Это довольно странно.

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

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

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

Это означает, что ==это сложно.

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

Что означает, что вы можете получить ошибки.

Так что мораль этой истории ...

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

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

Конец.

Автор: Luis Perez Размещён: 09.08.2016 04:50

68 плюса

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

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

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

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

Автор: Samar Panda Размещён: 05.09.2015 01:53

54 плюса

JavaScript === против == .

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
Автор: user2496033 Размещён: 03.07.2013 04:08

53 плюса

Это означает равенство без приведения типов Приведение типов означает, что 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 
Автор: Pop Catalin Размещён: 12.05.2010 12:59

48 плюса

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

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

Автор: Constantin Размещён: 16.12.2008 02:29

44 плюса

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

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

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

РАВНАЯ ТАБЛИЦА РАВНЫХ ОПЕРАТОРОВ В JAVASCRIPT

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

** СТРАННЫЙ: обратите внимание, что любые два значения в первом столбце не равны в этом смысле. **

''       == 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.
Автор: CuongHuyTo Размещён: 16.09.2011 02:25

38 плюса

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

Автор: Sean Размещён: 11.12.2008 02:44

37 плюса

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

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

введите описание изображения здесь

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

<script>

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

</script>

</head>

<body onload='onPageLoad();'>

Вы получите « ложь » в тревоге. Теперь измените onPageLoad()метод, чтобы alert(x == 5);вы получили истинное значение .

Автор: Aniket Thakur Размещён: 14.11.2014 06:02

34 плюса

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

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

Автор: Niraj CHoubey Размещён: 12.05.2010 01:03

32 плюса

Это строгий проверочный тест.

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

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

$a = 0;

Затем:

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

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

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

$a = 0;

$a===0; // returns true
$a===NULL; // returns false
$a===false; // returns false
Автор: Daniel Размещён: 12.05.2010 01:19

31 плюса

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

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

So, IMHO, JSLint maybe used to write new code, but useless over-optimizing should be avoided at all costs.

Meaning, there is no reason to change == to === in a check like if (a == 'test') when you know it for a fact that a can only be a String.

Modifying a lot of code that way wastes developers' and reviewers' time and achieves nothing.

Автор: ashes Размещён: 05.06.2012 07:53

30 плюса

Simply

== means comparison between operands with type conversion

&

=== means comparison between operands without type conversion

Type conversion in javaScript means javaScript automatically convert any other data types to string data types.

For example:

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 
Автор: Amit Размещён: 20.03.2015 05:05

26 плюса

A simple example is

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

2 === '2'  -> false, values are NOT SAME because of no type conversion.
Автор: Vikas Размещён: 14.05.2015 02:45

24 плюса

As a rule of thumb, I would generally use === instead of == (and !== instead of !=).

Reasons are explained in in the answers above and also Douglas Crockford is pretty clear about it (JavaScript: The Good Parts).

However there is one single exception: == null is an efficient way to check for 'is null or undefined':

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

For example jQuery 1.9.1 uses this pattern 43 times, and the JSHint syntax checker even provides the eqnull relaxing option for this reason.

From the jQuery style guide:

Strict equality checks (===) should be used in favor of ==. The only exception is when checking for undefined and null by way of null.

// Check for both undefined and null values, for some important reason. 
undefOrNull == null;
Автор: mar10 Размещён: 27.04.2013 02:15

24 плюса

The top 2 answers both mentioned == means equality and === means identity. Unfortunately, this statement is incorrect.

If both operands of == are objects, then they are compared to see if they are the same object. If both operands point to the same object, then the equal operator returns true. Otherwise, the two are not equal.

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

In the code above, both == and === get false because a and b are not the same objects.

That's to say: if both operands of == are objects, == behaves same as ===, which also means identity. The essential difference of this two operators is about type conversion. == has conversion before it checks equality, but === does not.

Автор: Harry He Размещён: 09.09.2013 08:31

22 плюса

The problem is that you might easily get into trouble since JavaScript have a lot of implicit conversions meaning...

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

Which pretty soon becomes a problem. The best sample of why implicit conversion is "evil" can be taken from this code in MFC / C++ which actually will compile due to an implicit conversion from CString to HANDLE which is a pointer typedef type...

CString x;
delete x;

Which obviously during runtime does very undefined things...

Google for implicit conversions in C++ and STL to get some of the arguments against it...

Автор: Thomas Hansen Размещён: 29.12.2008 11:54

22 плюса

From the core javascript reference

=== Returns true if the operands are strictly equal (see above) with no type conversion.

Автор: Paul Butcher Размещён: 12.05.2010 12:59

21 плюса

Equality comparison:

Operator ==

Returns true, when both operands are equal. The operands are converted to the same type before being compared.

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

Equality and type comparison:

Operator ===

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

>>> 1 === '1'
false
>>> 1 === 1
true
Автор: user2601995 Размещён: 02.10.2013 09:54

19 плюса

* Операторы === против == *

1 == true    =>    true
true == true    =>    true
1 === true    =>    false
true === true    =>    true
Автор: Mr.G Размещён: 19.03.2014 12:08

19 плюса

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

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

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

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

Автор: Christian Hagelid Размещён: 27.03.2014 12:18
Вопросы из категории :
32x32