operators || - Qual operador de igual(==vs===)deve ser usado em comparações de JavaScript?



&& js (25)

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

Estou usando o JSLint para percorrer o JavaScript, e ele está retornando muitas sugestões para substituir == (dois sinais de igual) com === (três sinais de igual) ao fazer coisas como comparar idSele_UNVEHtype.value.length == 0 dentro de um if declaração.

Existe um benefício de desempenho para substituir == por === ?

Qualquer melhoria de desempenho seria bem-vinda, já que existem muitos operadores de comparação.

Se nenhuma conversão de tipo ocorrer, haverá um ganho de desempenho em relação a == ?


Uma interessante representação pictórica da comparação de igualdade entre == e === .

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

var1 === var2

Ao usar === para testes de igualdade JavaScript, tudo é como está. Nada é convertido antes de ser avaliado.

var1 == var2

Ao usar == para testes de igualdade de JavaScript, algumas conversões de funky acontecem.

Moral da história:

Use === menos que você entenda totalmente as conversões que ocorrem com == .


Ele verifica se os mesmos lados são iguais em tipo e valor .

Exemplo:

'1' === 1 // will return "false" because `string` is not a `number`

Exemplo comum:

0 == ''  // will be "true", but it's very common to want this check to be "false"

Outro exemplo comum:

null == undefined // returns "true", but in most cases a distinction is necessary

Eu testei isso no Firefox com o Firebug usando código como este:

console.time("testEquality");
var n = 0;
while(true) {
    n++;
    if(n==100000) 
        break;
}
console.timeEnd("testEquality");

e

console.time("testTypeEquality");
var n = 0;
while(true) {
    n++;
    if(n===100000) 
        break;
}
console.timeEnd("testTypeEquality");

Meus resultados (testados cinco vezes cada e média):

==: 115.2
===: 114.4

Então eu diria que a diferença minúscula (isso é mais de 100.000 iterações, lembre-se) é insignificante. O desempenho não é um motivo para fazer === . Digite segurança (bem, tão seguro quanto você vai entrar em JavaScript), e a qualidade do código é.


Em um roteiro típico não haverá diferença de desempenho. Mais importante pode ser o fato de que mil "===" é 1 KB mais pesado do que mil "==" :) Os profilers JavaScript podem dizer se existe uma diferença de desempenho no seu caso.

Mas pessoalmente eu faria o que o JSLint sugere. Esta recomendação não está lá por causa de problemas de desempenho, mas porque meios de coerção de tipo ('\t\r\n' == 0) são verdadeiros.


Simplesmente

==significa comparação entre operandos com type conversion

E

===significa comparação entre operandos sem type conversion

A conversão de tipo em javaScript significa que o javaScript converte automaticamente quaisquer outros tipos de dados em tipos de dados de string.

Por exemplo:

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 

Deixe-me adicionar este conselho:

Em caso de dúvida, leia a specification !

ECMA-262 é a especificação para uma linguagem de script da qual o JavaScript é um dialeto. É claro que, na prática, importa mais como os navegadores mais importantes se comportam do que uma definição esotérica de como algo deve ser tratado. Mas é útil entender porque o novo String ("a")! == "a" .

Por favor, deixe-me explicar como ler a especificação para esclarecer esta questão. Eu vejo que neste tópico muito antigo ninguém tinha uma resposta para o efeito muito estranho. Então, se você puder ler uma especificação, isso o ajudará tremendamente em sua profissão. É uma habilidade adquirida. Então, vamos continuar.

A pesquisa no arquivo PDF por === me leva à página 56 da especificação: 11.9.4. O operador Strict Equals (===) , e depois de percorrer o specificationalese eu acho:

11.9.6 O algoritmo de comparação de igualdade estrita
A comparação x === y, onde x e y são valores, produz true ou false . Tal comparação é realizada da seguinte forma:
1. Se Type (x) for diferente de Type (y), retorne false .
2. Se Type (x) for indefinido, retorne true .
3. Se o Tipo (x) for Nulo, retorne verdadeiro .
4. Se Type (x) não for Number, vá para a etapa 11.
5. Se x for NaN , retorne false .
6. Se y for NaN , retorne false .
7. Se x for o mesmo valor numérico de y, retorne true .
8. Se x for +0 e y for −0, retorne verdadeiro .
9. Se x for −0 e y for +0, retorne verdadeiro .
10. Retorne falso .
11. Se Type (x) for String, então retorne true se xey forem exatamente a mesma seqüência de caracteres (mesmo comprimento e mesmos caracteres nas posições correspondentes); Caso contrário, retorne false .
12. Se Type (x) for booleano, retorne true se x e y forem ambos verdadeiros ou ambos falsos ; Caso contrário, retorne false .
13. Retorna verdadeiro se xey se referir ao mesmo objeto ou se eles se referirem a objetos unidos entre si (ver 13.1.2). Caso contrário, retorne falso .

Interessante é o passo 11. Sim, as strings são tratadas como tipos de valor. Mas isso não explica porque o novo String ("a")! == "a" . Temos um navegador que não está em conformidade com o ECMA-262?

Não tão rápido!

Vamos verificar os tipos dos operandos. Experimente você mesmo, envolvendo-os em typeof () . Eu acho que new String ("a") é um objeto, e a etapa 1 é usada: return false se os tipos forem diferentes.

Se você quer saber por que o novo String ("a") não retorna uma string, que tal um exercício lendo uma especificação? Diverta-se!

Aidiakapi escreveu isto em um comentário abaixo:

A partir da especificação

11.2.2 O novo Operador :

Se Type (construtor) não for Object, lance uma exceção TypeError.

Com outras palavras, se String não fosse do tipo Object, não poderia ser usado com o novo operador.

new sempre retorna um Object, mesmo para os construtores String , também. E ai! A semântica do valor para strings (consulte a etapa 11) é perdida.

E isso finalmente significa: new String ("a")! == "a" .


Nas respostas aqui, eu não li nada sobre o que significa igualdade . Alguns dirão que === significa igual e do mesmo tipo , mas isso não é verdade. Na verdade, significa que ambos os operandos fazem referência ao mesmo objeto ou, no caso de tipos de valor, possuem o mesmo valor .

Então, vamos pegar o seguinte código:

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

O mesmo aqui:

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

Ou até mesmo:

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

Esse comportamento nem sempre é óbvio. Há mais na história do que ser igual e ser do mesmo tipo.

A regra é:

Para tipos de valor (números):
a === b retorna verdadeiro se a e b tiverem o mesmo valor e forem do mesmo tipo

Para tipos de referência:
a === b retorna verdadeiro se a e b referência exatamente ao mesmo objeto

Para strings:
a === b retorna verdadeiro se a e b forem ambos strings e contiverem exatamente os mesmos caracteres

Cordas: o caso especial ...

Strings não são tipos de valor, mas em Javascript eles se comportam como tipos de valor, então eles serão "iguais" quando os caracteres na string forem os mesmos e quando forem do mesmo tamanho (como explicado na terceira regra)

Agora fica interessante:

var a = "12" + "3";
var b = "123";

alert(a === b); // returns true, because strings behave like value types

Mas e quanto a isso ?:

var a = new String("123");
var b = "123";

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

Eu pensei que as cordas se comportam como tipos de valor? Bem, depende de quem você pergunta ... Neste caso, a e b não são do mesmo tipo. a é do tipo Object , enquanto b é do tipo string . Apenas lembre-se de que criar um objeto string usando o construtor String cria algo do tipo Object que se comporta como uma string na maior parte do tempo .


O operador === é chamado de operador de comparação estrita, ele difere do operador == .

Vamos tomar 2 vars a e b.

Para "a == b" para avaliar como verdadeiro a e b precisam ser o mesmo valor .

No caso de "a === b", a e b devem ter o mesmo valor e também o mesmo tipo para serem avaliados como verdadeiros.

Tome o seguinte exemplo

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

Em resumo ; usar o operador == pode ser avaliado como verdadeiro em situações em que você não deseja, portanto, usar o operador === seria mais seguro.

No cenário de uso de 90%, não importa qual você usar, mas é útil saber a diferença quando você obtém algum comportamento inesperado um dia.


Sim! Isto é importante.

===O operador no javascript verifica o valor e digita onde, como ==operador, apenas verifica o valor (faz conversão se necessário) .

Você pode facilmente testá-lo. Cole o seguinte código em um arquivo HTML e abra-o no navegador

<script>

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

</script>

</head>

<body onload='onPageLoad();'>

Você vai ficar " falso " em alerta. Agora modifique o onPageLoad()método para alert(x == 5);você se tornar realidade .


* Operadores === vs == *

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

nulo e indefinido são nada, isto é,

var a;
var b = null;

Aqui ae bnão tem valores. Considerando que, 0, falso e '' são todos os valores. Uma coisa comum entre todos estes é que eles são todos valores falsos, o que significa que todos eles satisfazem condições falsas.

Então, o 0, falso e '' juntos formam um subgrupo. E por outro lado, null e undefined formam o segundo subgrupo. Verifique as comparações na imagem abaixo. null e indefinido seria igual. Os outros três seriam iguais entre si. Mas todos eles são tratados como falsas condições em JavaScript.

Isso é o mesmo que qualquer objeto (como {}, matrizes, etc.), string não vazia e true booleano são todas as condições verdadeiras. Mas todos eles não são iguais.


Diagrama de fluxo de execução de Javascript para igualdade estrita / Comparação '==='

Fluxograma de execução Javascript para igualdade / comparação não estrita '=='


Como regra geral, eu usaria geralmente em ===vez de ==(e em !==vez de !=).

Razões são explicadas nas respostas acima e também Douglas Crockford é bastante claro sobre isso ( JavaScript: The Good Parts ).

No entanto, há uma única exceção : == nullé uma maneira eficiente de verificar se 'é nulo ou indefinido':

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

Por exemplo, o jQuery 1.9.1 usa esse padrão 43 vezes, e o verificador de sintaxe do JSHint também fornece a eqnullopção relaxante por esse motivo.

Do guia de estilo do jQuery :

Verificações estritas de igualdade (===) devem ser usadas em favor de ==. A única exceção é ao verificar undefined e null por meio de null.

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

O problema é que você pode facilmente ter problemas, pois o JavaScript tem muitas conversões implícitas, o que significa ...

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

Que logo se torna um problema. A melhor amostra de por que a conversão implícita é "maligna" pode ser obtida deste código no MFC / C ++ que, na verdade, será compilado devido a uma conversão implícita de CString para HANDLE, que é um tipo typedef de ponteiro ...

CString x;
delete x;

Que, obviamente, durante o tempo de execução faz coisas muito indefinidas ...

Google para conversões implícitas em C ++ e STL para obter alguns dos argumentos contra ...


É improvável que haja qualquer diferença de desempenho entre as duas operações no seu uso. Não há conversão de tipo a ser feita porque os dois parâmetros já são do mesmo tipo. Ambas as operações terão uma comparação de tipo seguida por uma comparação de valor.


O operador de comparação igual == é confuso e deve ser evitado.

Se você tem que viver com isso, então lembre-se das seguintes 3 coisas:

  1. Não é transitivo: (a == b) e (b == c) não leva a (a == c)
  2. É mutuamente exclusivo à sua negação: (a == b) e (a! = B) sempre mantêm valores booleanos opostos, com todos aeb.
  3. Em caso de dúvida, aprenda de cor a seguinte tabela de verdade:

TABELA DE VERDADE DE OPERADOR IGUAL EM JAVASCRIPT

  • Cada linha na tabela é um conjunto de 3 valores mutuamente "iguais", o que significa que quaisquer 2 valores entre eles são iguais usando o sinal igual == *

** STRANGE: observe que quaisquer dois valores na primeira coluna não são iguais nesse sentido. **

''       == 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.

O JSLint às vezes lhe dá razões irreais para modificar o material. ===tem exatamente o mesmo desempenho como ==se os tipos já fossem os mesmos.

Só é mais rápido quando os tipos não são os mesmos e, nesse caso, não tenta converter tipos, mas retorna diretamente um falso.

Então, IMHO, o JSLint talvez seja usado para escrever código novo, mas a otimização excessiva inútil deve ser evitada a todo custo.

Ou seja, não há razão para mudar ==para ===um cheque como if (a == 'test')quando você sabe que um só pode ser uma String.

Modificar muito código dessa maneira desperdiça tempo dos desenvolvedores e revisores e não alcança nada.


Um exemplo simples é

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

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

=== O operador verifica os valores, bem como os tipos das variáveis ​​para igualdade.

== operador apenas verifica o valor das variáveis ​​para igualdade.


Comparação de igualdade:

Operador ==

Retorna true, quando os dois operandos são iguais. Os operandos são convertidos para o mesmo tipo antes de serem comparados.

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

Igualdade e comparação de tipos:

Operador ===

Retorna true se ambos os operandos forem iguais e do mesmo tipo. Em geral, é melhor e mais seguro se você comparar dessa maneira, porque não há conversões de tipo por trás das cenas.

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

Em PHP e JavaScript, é um operador de igualdade estrito. O que significa que irá comparar o tipo e os valores.


Por que é tão imprevisível?

O que você ganha quando compara uma string vazia "" com o número zero 0 ?

true

Sim, isso é certo de acordo com == uma seqüência vazia e o número zero são o mesmo tempo.

E não termina aí, aqui está outro:

'0' == false // true

As coisas ficam muito estranhas com matrizes.

[1] == true // true
[] == false // true
[[]] == false // true
[0] == false // true

Então mais estranho com cordas

[1,2,3] == '1,2,3' // true - REALLY?!
'\r\n\t' == 0 // true - Come on!

Fica pior:

Quando é igual não é igual?

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!

Deixe-me dizer isso de novo:

(A == B) && (B == C) // true
(A == C) // **FALSE**

E isso é apenas o material maluco que você começa com primitivos.

É um novo nível de loucura quando você usa == com objetos.

Neste momento você provavelmente está se perguntando ...

Por que isso acontece?

Bem, é porque ao contrário de "triplo é igual" ( === ) que apenas verifica se dois valores são os mesmos.

== faz um monte de outras coisas .

Tem tratamento especial para funções, tratamento especial para nulos, indefinido, strings, o nome dele.

Isso é muito maluco.

De fato, se você tentou escrever uma função que faz o que == seria algo como isto:

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

Então o que isso quer dizer?

Isso significa que == é complicado.

Porque é complicado, é difícil saber o que vai acontecer quando você usá-lo.

O que significa que você pode acabar com bugs.

Então a moral da história é ...

Torne sua vida menos complicada.

Use === vez de == .

O fim.


Usando o operador == ( Equality )

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

Usando o operador === ( Identity )

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

Isso ocorre porque o operador de igualdade == faz coerção de tipo , significando que o interpretador tenta implicitamente converter os valores antes de comparar.

Por outro lado, o operador de identidade === não faz coerção de tipo e, portanto, não converte os valores ao comparar.


Esta é uma tentativa de esclarecer vários (possíveis) mal-entendidos sobre encerramentos que aparecem em algumas das outras respostas.

  • Um fechamento não é criado apenas quando você retorna uma função interna.De fato, a função delimitadora não precisa retornar de forma alguma para que seu fechamento seja criado. Você pode, em vez disso, atribuir sua função interna a uma variável em um escopo externo ou passá-la como um argumento para outra função em que ela possa ser chamada imediatamente ou em qualquer momento posterior. Portanto, o fechamento da função delimitadora é provavelmente criado assim que a função delimitadora é chamada, uma vez que qualquer função interna tem acesso a esse fechamento sempre que a função interna é chamada, antes ou depois que a função delimitadora retorna.
  • Um encerramento não faz referência a uma cópia dos valores antigos de variáveis ​​em seu escopo. As variáveis ​​em si fazem parte do fechamento e, portanto, o valor visto ao acessar uma dessas variáveis ​​é o valor mais recente no momento em que é acessado. É por isso que funções internas criadas dentro de loops podem ser complicadas, já que cada uma tem acesso às mesmas variáveis ​​externas em vez de pegar uma cópia das variáveis ​​no momento em que a função é criada ou chamada.
  • As "variáveis" em um fechamento incluem quaisquer funções nomeadas declaradas dentro da função. Eles também incluem argumentos da função. Um fechamento também tem acesso às suas variáveis ​​de fechamento, até o escopo global.
  • Fechamentos usam memória, mas eles não causam vazamentos de memória, já que o JavaScript, por si só, limpa suas próprias estruturas circulares que não são referenciadas. Os vazamentos de memória do Internet Explorer que envolvem closures são criados quando ele não desconecta os valores do atributo DOM que fazem referência a closures, mantendo assim referências a estruturas possivelmente circulares.




javascript operators equality equality-operator identity-operator