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


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

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

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

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

30   5673   0000-00-00 00:00:00

30 ответов:

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

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

The == оператор сравнения на равенство после выполнения всех необходимых преобразований типов. Элемент === оператор не сделать преобразование, так что если два значения не тот же тип === просто 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 в комментариях и в @Филипп 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 конструктор для создания строковых объектов.

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

например,

4 == "4" // will return true

но

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

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

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

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

пример:

'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) - Это правда.

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

Если вы ОБЯЗАТЕЛЬНО живите с этим, а затем помните следующие 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.

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

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

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

enter image description here

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

<script>

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

</script>

</head>

<body onload='onPageLoad();'>

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

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

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

это строгий тест проверки.

это хорошо, особенно если вы проверяете между 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 это эффективный способ проверить 'is null or undefined':
if( value == null ){
    // value is either null or undefined
}

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

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

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

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

С основная ссылка на javascript

=== возвращает 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 - все условия истинности. Но, они все не равны.