javascript - типов - сравнение строк js




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

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

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

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

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


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

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

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

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

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


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

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


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

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

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 и тот же объект

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


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


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

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

var1 === var2

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

var1 == var2

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

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

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


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

Пример:

'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

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

Давайте возьмем 2 vars 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");
}

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

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


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

Если есть сомнения, прочтите specification !

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) не определен, верните 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 Новый оператор :

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

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

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

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


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

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


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

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

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

$a = 0;

Затем:

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

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

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

$a = 0;

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

Я тестировал это в 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 вещи:

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

EQUAL OPERATOR TRUTH TABLE В 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.

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

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

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

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

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

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

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

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

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

Конец.


null и undefined - ничто, т. е.

var a;
var b = null;

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

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

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


Просто

==означает сравнение между операндами с 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 ответа на оба упомянутых == означает равенство и === означает идентификацию. К сожалению, это утверждение неверно.

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

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

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

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






identity-operator