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

5956

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

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

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

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

  • 2
    Вот диаграмма того, как сравниваются некоторые «ложные» значения.
  • 134
    Кому это может быть интересно на ту же тему === vs == , но на PHP, можете прочитать здесь: stackoverflow.com/questions/2401478/why-is-faster-than-in-php/…
Показать ещё 13 комментариев
Теги:
operators
equality
equality-operator
identity-operator

51 ответ

6132
Лучший ответ

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

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

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

Процитировать Douglas Crockford отлично 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

  • 4
    Итак, если предположить, что типы одинаковы - действительно ли === быстрее? :)
  • 210
    === не быстрее, если типы одинаковы. Если типы не совпадают, === будет быстрее, потому что не будет пытаться выполнить преобразование.
Показать ещё 43 комментария
1066

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

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

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

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

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

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

  • 9
    @Software Monkey: не для типов значений (число, логическое значение, ...)
  • 0
    type coercion vs type casting vs type convertion : stackoverflow.com/questions/8857763/…
Показать ещё 3 комментария
536

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

  • 6
    activa: Я хотел бы уточнить, что строки так равны только тогда, когда они являются литералами. new String ("abc") === "abc" - false (согласно моим исследованиям).
  • 3
    new Number() == "0" . Также в Firefox: (function(){}) == "function () {\n}"
Показать ещё 9 комментариев
526

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

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


var1 === var2

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

Изображение 2000


var1 == var2

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

Изображение 2001

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

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

  • 0
    Я бы пошел еще дальше с моралью: всегда используйте === /! ===, но поймите преобразование, чтобы иметь возможность справляться с чужим кодом
  • 0
    текущая реализация этой таблицы находится здесь: yolpo.com/embed.html?gist=344311f27fd88a9c2be8
Показать ещё 7 комментариев
242

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

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

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" .

  • 0
    Результат типа (x) подразумевается как typeof?
  • 0
    @nalply Я не совсем понимаю беспокойство по поводу поведения с new String('x') , потому что я никогда не видел ни одного кода в дикой природе, который использует примитивные объекты-обертки, и я не думаю, что есть много веских причин, чтобы особенно не в наши дни. Вы когда-нибудь сталкивались с кодом, который делает?
Показать ещё 2 комментария
99

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

  • 9
    @ Дэвид: правильно. Вот почему этот ответ неточный (или даже неправильный)
  • 6
    @David var a = {}, b = {}; a == b возвращает false.
Показать ещё 3 комментария
92

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

Например,

4 == "4" // will return true

но

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

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

  • 3
    Больше, чем безопасность типов, вам нужна логическая корректность - иногда вы хотите, чтобы все было правдиво, когда == не согласен.
  • 4
    Теперь, как они сравниваются, когда есть фактическое приведение типа для оператора == ? Помните, что именно тогда происходит повышение производительности.
Показать ещё 1 комментарий
74

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

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

71

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

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

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

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

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

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

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

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

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

Конец.

  • 0
    Ваш looseEqual неверен. Function == Function.toString() имеет значение true, looseEqual(Function, Function.toString()) имеет значение false. Не уверен, почему вы отфильтровываете функции в начале.
  • 0
    @ Orol, вы были правы, я обновил код, чтобы учесть это, к вашему сведению, на основании моих тестов было недостаточно убрать фильтр для «функций», вместо этого «функции» должны были обрабатываться совсем по-другому.
Показать ещё 4 комментария
67

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

Пример:

'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
  • 7
    также 'string' !== 'number'
66

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

Изображение 2002

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

Изображение 2003

  • 0
    Я не понимаю, почему string стрелка указывает на большую серую коробку, это должно означать, что прерыватель отбрасывает строку в число?
  • 0
    @vsync Указывает на параметр строки внутри серого поля, т. е. строка -> # || NaN. Javascript не является языком сценариев типов, то есть в основном он может иметь любой тип переменной. Итак, он указывает на эту серую коробку.
Показать ещё 2 комментария
52

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
49

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

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

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

  • 4
    Не всегда правда. При сжатии gzip разница будет почти незначительной.
  • 1
    Согласитесь, но тысяча "===" означает еще и 10 тысяч строк кода, так что более или менее 1 КБ ...;)
Показать ещё 1 комментарий
42

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

Если вы живете с ИМЕЕТЕ, помните следующие 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.
36

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

34

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

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

Изображение 2004

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

<script>

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

</script>

</head>

<body onload='onPageLoad();'>

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

31
Оператор

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

Оператор

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

31

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

Это хорошо, особенно если вы проверяете между 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
  • 3
    В JavaScript это совершенно неправильно и ошибочно неполно. 0 != null . -1
28

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

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

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

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

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

27

Просто

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

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

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

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

Топ-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 не являются одними и теми же объектами.

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

22

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

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

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

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

Например, jQuery 1.9.1 использует этот шаблон 43 раза, а руководство по стилю jQuery:

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

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

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

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

21

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

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

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

CString x;
delete x;

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

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

  • 1
    0 == null это ложь.
20

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

Оператор ==

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

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

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

Оператор ===

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

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

null и undefined - небытие, то есть

var a;
var b = null;

Здесь a и b не имеют значений. Принимая во внимание, что 0, false и '' - все значения. Одно из них заключается в том, что все они являются ложными значениями, а это означает, что все удовлетворяют условиям фальшивости.

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

Изображение 2005

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

18

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

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

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

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

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

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

16

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

  • Оператор равенства (==) преобразует операнды, если они не одного типа, а затем применяет строгое сравнение. Если любой операнд является числом или логическим, операнды, если это возможно, преобразуются в числа; else, если любой операнд является строкой, операнд строки преобразуется в число, если это возможно. Если оба операнда являются объектами, тогда JavaScript сравнивает внутренние ссылки, равные, когда операнды относятся к одному и тому же объекту в памяти.

    Синтаксис:

    x == y

    Примеры:

    3 == 3     // true
    "3" == 3   // true
    3 == '3'   // true
    
  • Оператор identity/strict равен (===) возвращает true, если операнды строго равны (см. Выше) без преобразования типа.

    Синтаксис:

    x === y

    Примеры:

    3 === 3//true

Для справки: Операторы сравнения (Mozilla Developer Network)

15

Если вы создаете веб-приложение или защищенную страницу, вы всегда должны использовать (только когда это возможно)

===

потому что он будет проверять, является ли он одним и тем же контентом и является ли он одним и тем же типом!

поэтому, когда кто-то входит:

var check = 1;
if(check == '1') {
    //someone continued with a string instead of number, most of the time useless for your webapp, most of the time entered by a user who does not now what he is doing (this will sometimes let your app crash), or even worse it is a hacker searching for weaknesses in your webapp!
}

но с

var check = 1;
if(check === 1) {
    //some continued with a number (no string) for your script
} else {
    alert('please enter a real number');
}

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

Я хочу сказать, что

===

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

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

Причина, по которой я опубликовал это, заключается в том, что слово "более безопасное" или "безопасность" никогда не упоминалось в этом разговоре (если вы посмотрите на iCloud.com, он использует 2019 раз === и 1308 раз ==, это также означает, что у вас иногда есть использование == вместо ===, потому что он в противном случае блокирует вашу функцию, но, как сказано в начале, вы должны использовать === как можно больше)

12

Мой процесс рассуждений с использованием emacs org-mode и node.js для запуска теста.

| use =      | '' | '0' | false | 'false' | undefined | null | ' \t\r\n ' |
| ''         | x  | f   | t     | f       | f         | f    | f          |
| '0'        |    | x   | t     | f       | f         | f    | f          |
| false      |    |     | x     | f       | f         | f    | t          |
| 'false'    |    |     |       | x       | f         | f    | f          |
| undefined  |    |     |       |         | x         | t    | f          |
| null       |    |     |       |         |           | x    | f          |
| ' \t\r\n ' |    |     |       |         |           |      | x          | 



| use ===    | '' | '0' | false | 'false' | undefined | null | ' \t\r\n ' |
| ''         | x  | f   | f     | f       | f         | f    | f          |
| '0'        |    | x   | f     | f       | f         | f    | f          |
| false      |    |     | x     | f       | f         | f    | f          |
| 'false'    |    |     |       | x       | f         | f    | f          |
| undefined  |    |     |       |         | x         | f    | f          |
| null       |    |     |       |         |           | x    | f          |
| ' \t\r\n ' |    |     |       |         |           |      | x          |

Мой тест script ниже: run > node xxx.js

var rowItems = ['', '0', false, 'false', undefined, null, ' \t\r\n ']
var colItems = rowItems

for(var i = 0; i < rowItems.length; i++) {
    for (var j = 0; j < colItems.length; j++) {
        var r = (rowItems[i] === colItems[j]) ? true : false;
        console.log(rowItems[i] + " = " + colItems[j] + " " + r + " [" + i + "] ==> [" + j + "]")
    };
}
  • 0
    Разве это не должно быть use == вместо use = в вашей первой таблице?
  • 0
    @le_m === более строг, чем =, поэтому он находится в правильном порядке, а не наоборот.
Показать ещё 1 комментарий
12

=== заботится, будут ли объекты одинаковыми. Поэтому new String("Hello world") === "Hello world" возвращает false. Однако == не заботится о том, являются ли объекты одинаковыми; он просто преобразует один аргумент в другой тип: если преобразование невозможно, верните false. Затем new String("Hello world") == "Hello world" возвращает true вместо false.

11

javascript - это слабо типизированный язык, т.е. без каких-либо типов данных, как в C, С++, например. int, boolean, float и т.д., поэтому переменная может содержать любой тип значения, поэтому эти специальные операторы сравнения есть

Например,

var i = 20;var j = "20";

если мы применяем операторы сравнения, результат этих переменных будет

i==j //result is true

или

j != i//result is false

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

если мы делаем

i===j //result is false
9

Разное =, = =, = = =

  • Оператор
  • = Используется для назначения value. Оператор
  • = = Используется для сравнения values not datatype Оператор
  • = = = Используется для сравнения values, а также datatype.
7

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

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

например.

1 == "1" //true

1 === "1" //false

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

  • 0
    для '==' dataType не важен
6

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

5

Одна неоспоримая причина использования === - заключается в том, что вы совместно существуете с/кросс-компиляцией в/из coffee-script. Из маленькой книги на CoffeeScript...

Слабое сравнение равенства в JavaScript имеет какое-то запутанное поведение и часто является источником запутывающих ошибок.

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

Если вы регулярно переходите на coffee-script, вы должны просто использовать ===. Фактически, компилятор coffee-script заставит вас...

CoffeeScript решает это, просто заменяя все слабые сравнения на строгие, другими словами превращая все == compators в ===. Вы не можете сделать небольшое сравнение равенства в CoffeeScript, и вы должны явно преобразовать типы, прежде чем сравнивать их, если это необходимо.

5

Да, существует большая разница между операторами равенства == и identity ===.
Обычно оператор идентификации работает быстрее, потому что преобразование типов не выполняется. Но если значения одного типа, вы не увидите различий.
Проверьте мой пост Легенда оператора равенства JavaScript, в котором объясняются детали, в том числе алгоритмы преобразования и сравнения типов, с большим количеством примеров.

3

Строгое равенство по большей части лучше

Тот факт, что Javascript является свободно типизированным языком, должен постоянно находиться в вашем сознании, когда вы работаете с ним. Пока структура данных одинакова, на самом деле нет причин не использовать строгое равенство, при регулярном равенстве вы часто имеете неявное преобразование значений, которое происходит автоматически, это может иметь далеко идущие последствия для вашего кода. Очень легко иметь проблемы с этим преобразованием, поскольку они происходят автоматически.

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

1

Дилемма "Должен ли я использовать == или === в сравнении с JavaScript" равна или аналогична вопросу: "Должен ли я использовать" ложку "или" вилку "для еды.

Единственный разумный ответ на этот вопрос:

  • Вам следует использовать сравнение Динамический тип, например: == для сравнения свободно.
  • Вам следует использовать сравнение Статический тип, например: === для сопоставлений сильного типа.

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

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

Значение: вы решите использовать "ложку" i.e.: == за наличие "супа" и/или "fork" i.e.: === для выбора.

Запрашивая, лучше ли использовать "вилку" или "ложку" для "еды" - равносильно спросить, лучше ли использовать статический [===] против динамического [==] экв., соч. в JS. Оба вопроса одинаково ошибочны и отражают очень узкое или мелкое понимание предмета, о котором идет речь.

  • 0
    ps: JSLint (или Crockford) не подходит для того, чтобы настаивать или просить вас использовать строгое сравнение типов при работе со значениями того же типа. Свойство length JavaScript всегда имеет тип: число. И поэтому нет места или возможности для поддельных позитивов. Кроме того, нет необходимости в dSele_UNVEHtype.value.length === 0 когда вместо этого можно использовать прямое сокращение !dSele_UNVEHtype.value.length .
  • 2
    Зачем вам отвечать на 9-летний вопрос, на который уже есть 49 ответов, на который также есть принятый ответ с более чем 5 тысячами голосов, ответ на который содержит странную аналогию и ничего не объясняет того, что еще не было сказано?
Показать ещё 3 комментария
1

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

1

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

Строгое равенство с использованием ===

Строгое равенство сравнивает два значения для равенства. Ни одно из значений неявно преобразуется в какое-либо другое значение перед сравнением. Если значения имеют разные типы, значения считаются неравными. В противном случае, если значения имеют один и тот же тип и не являются номерами, они считаются равными, если они имеют одинаковое значение. Наконец, если оба значения - это числа, они считаются равными, если они оба не NaN и являются одним и тем же значением, или если он равен +0, а один равен -0.

var num = 0;
var obj = new String('0');
var str = '0';

console.log(num === num); // true
console.log(obj === obj); // true
console.log(str === str); // true

console.log(num === obj); // false
console.log(num === str); // false
console.log(obj === str); // false
console.log(null === undefined); // false
console.log(obj === null); // false
console.log(obj === undefined); // false


Свободное равенство с использованием ==

Свободное равенство сравнивает два значения для равенства, после преобразования обоих значения для общего типа. После конверсий (одна или обе стороны могут претерпевают конверсии), выполняется окончательное сравнение равенства точно так же, как === выполняет. Свободное равенство симметрично: A == B всегда имеет идентичную семантику для B == A для любых значений A и B (за исключением порядка применяемых преобразований).

var num = 0;
var obj = new String('0');
var str = '0';

console.log(num == num); // true
console.log(obj == obj); // true
console.log(str == str); // true

console.log(num == obj); // true
console.log(num == str); // true
console.log(obj == str); // true
console.log(null == undefined); // true

// both false, except in rare cases
console.log(obj == null);
console.log(obj == undefined);
  • 0
    Я действительно считаю, что это субъективно в отношении того, что вы должны / не должны делать, и вводит в заблуждение, чтобы сказать кому-то всегда использовать определенное действие. Хотя я согласен с тем, что в большинстве случаев мы хотим использовать «===» против «==», в некоторых случаях может потребоваться выполнить преобразование типа. - Не могу придумать точного варианта использования на макушке моей головы, но, возможно, дизайн - это чек. Независимо от того, если что-то включено в язык, оно есть по причине. Мы должны стараться избегать общих утверждений «всегда делай х» на мой взгляд.
  • 0
    Я согласен с вами, если вы прочитаете весь мой ответ, вы увидите, что я объясню более подробно позже, если честно, мы используем не так много случаев и нуждаемся в свободном сравнении в Javascript ... Я могу сказать менее 5 процентов и даже намного меньше, но я использую «всегда» для тех, кто не имеет опыта работы с js, которые думают, что == проверяют строгое сравнение в JavaScript, они учатся быть усталыми и не используют его с самого начала, но по мере того, как они становятся более опытными, они знать, в каких редких случаях они могут его использовать. Вот почему я так пишу свой ответ.
1

Во-первых, некоторая терминология о строке Javascript равна: Double equals официально известна как абстрактный оператор сравнения равенства, в то время как тройное равенство называется строгим оператором сравнения равенства. Разницу между ними можно суммировать следующим образом: Абстрактное равенство будет пытаться разрешить типы данных посредством принуждения типа, прежде чем проводить сравнение. Строгое равенство вернет false, если типы разные. Рассмотрим следующий пример:

console.log(3 == "3"); // true
console.log(3 === "3"); // false.
console.log(3 == "3"); // true
console.log(3 === "3"); // false.

Использование двух равных знаков возвращает true, потому что строка "3" преобразуется в число 3 до начала сравнения. Три равных знака видят, что типы различны и возвращают false. Heres another:

console.log(true == '1'); // true
console.log(true === '1'); // false
console.log(true == '1'); // true
console.log(true === '1'); // false

Опять же, абстрактное сравнение равенства выполняет преобразование типа. В этом случае как логическое значение true, так и строка '1 преобразуются в число 1, и результат является истинным. Строгое равенство возвращает false.

Если вы понимаете, что на пути к различию между == и === хорошо. Тем не менее, есть некоторые сценарии, в которых поведение этих операторов неинтуитивно. Давайте рассмотрим еще несколько примеров:

console.log(undefined == null); // true
console.log(undefined === null); // false. Undefined and null are distinct types and are not interchangeable.
console.log(undefined == null); // true     
console.log(undefined === null); // false. Undefined and null are distinct types and are not interchangeable.

console.log(true == 'true'); // false. A string will not be converted to a boolean and vice versa.
console.log(true === 'true'); // false
console.log(true == 'true'); // false. A string will not be converted to a boolean and vice versa.
console.log(true === 'true'); // false

Пример ниже интересен тем, что он иллюстрирует, что строковые литералы отличаются от строковых объектов.

console.log("This is a string." == new String("This is a string.")); // true
console.log("This is a string." === new String("This is a string.")); // false
console.log("This is a string." == new String("This is a string.")); // true
console.log("This is a string." === new String("This is a string.")); // false
1

Javascript свободно набирается точно так же, как php,

var x = "20";
var y =20;

if (x===y) // false

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

Один - это строка, другая - int

If(x==y)//true

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

Я не хочу сказать, что значения равны, потому что строковое значение не может быть равно логическому значению int

0

== convertts, === нет. Я сделал видео с примером:

https://youtu.be/ik5E5n36K4U

0

=== лучше производительность, потому что это не тип проверки

Пример:

var a=1, b=1, c='1';    
a===b //is true and better performance
a==c  //is true but no good performance
0
var a = new String("123");
var b = "123";

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

Увидел это в одном из ответов. a и b в данном случае на самом деле не такие же, если вы проверите typeof(a)  вы получите "объект", а typeof(b) - "строка".

-3
1 == "1"    =>    true(define)
true === "true"    => false(undefined compare the type of variable)
Case 1
if(true === "true"){
  echo 'true'
}else{
 echo 'false undefined'
}
Ans :- false undefined because case 1 is check data type also with ===  
Case 2
if(1 == "1"){
  echo 'true define'
}else{
 echo 'false undefined'
}
Ans :- true define undefined because case 2 is not check data type with ==
  • 2
    Пожалуйста, объясните свой ответ.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню