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


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

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

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

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


5613


источник


Ответы:


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

Справка: Javascript Tutorial: Операторы сравнения

==оператор сравним для равенства после выполнения любых необходимых преобразований типов , ===оператор будет не сделайте преобразование, поэтому, если два значения не являются одним и тем же типом ===просто вернется 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's ответ относительно ссылочных типов. Для ссылочных типов ==а также ===действуют последовательно друг с другом (за исключением особого случая).

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


5624



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

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

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

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


971



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

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

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


533



Интересное иллюстрированное представление сравнения равенства между ==а также ===,

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


var1 var2 ===

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

Equality evaluation of === in JS


var1 == var2

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

Equality evaluation of == in JS


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


508



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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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


245



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


91



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


86



In JavaScript it means of the same value and type.

For example,

4 == "4" // will return true

but

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

82



The === operator is called a strict comparison operator, it does differ from the == operator.

Lets take 2 vars a and b.

For "a == b" to evaluate to true a and b need to be the same value.

In the case of "a === b" a and b must be the same value and also the same type for it to evaluate to true.

Take the following example

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

In summary; using the == operator might evaluate to true in situations where you do not want it to so using the === operator would be safer.

In the 90% usage scenario it won't matter which one you use, but it is handy to know the difference when you get some unexpected behaviour one day.


70