Qual operador igual (== vs ===) deve ser usado nas comparações de JavaScript?

5665

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

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

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

Se nenhuma conversão de tipo ocorrer, haverá um ganho de desempenho superior ==?

bcasp
fonte
134
Para quem possa estar interessado no mesmo assunto === vs ==, mas em PHP, pode ler aqui: stackoverflow.com/questions/2401478/why-is-faster-than-in-php/…
Marco Demaio
257
Apenas no caso de alguém estar se perguntando em 2012: ===é muito mais rápido que ==. jsperf.com/comparison-of-comparisons
Ry-
25
@minitech deve ser como ele não faz a conversão de tipo
Umur Kontacı
19
@minitech, duvido que alguém torne sua aplicação visivelmente mais rápida usando o ===excesso ==. De fato, o benchmark não mostra uma grande diferença entre ambos nos navegadores modernos. Pessoalmente, eu costumo usar em ==qualquer lugar, a menos que eu realmente precise de uma igualdade estrita.
laurent
5
Aqui é a parte do Crockford JS The Good Parts conversa onde ele discute as ===e ==operadores: youtube.com/... Se ele não jogar, é a 15:20
davidhiggins

Respostas:

6486

O operador de igualdade estrita ( ===) se comporta de forma idêntica ao operador de igualdade abstrata ( ==), exceto que nenhuma conversão de tipo é feita e os tipos devem ser os mesmos para serem considerados iguais.

Referência: Tutorial Javascript: Operadores de Comparação

O ==operador comparará a igualdade depois de realizar as conversões de tipo necessárias . O ===operador não fará a conversão; portanto, se dois valores não forem do mesmo tipo ===, retornará simplesmente false. Ambos são igualmente rápidos.

Para citar o excelente JavaScript de Douglas Crockford : The Good Parts ,

JavaScript tem dois conjuntos de operadores de igualdade: ===e !==, e seus gêmeos maus ==e !=. Os bons funcionam da maneira que você esperaria. Se os dois operandos forem do mesmo tipo e tiverem o mesmo valor, ===produz truee !==produz false. Os gêmeos maus fazem a coisa certa quando os operandos são do mesmo tipo, mas se são de tipos diferentes, tentam coagir os valores. as regras pelas quais eles fazem isso são complicadas e imemoráveis. Estes são alguns dos casos interessantes:

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

Tabela de comparação de igualdade

A falta de transitividade é alarmante. Meu conselho é nunca usar os gêmeos do mal. Em vez disso, sempre use ===e !==. Todas as comparações mostradas são produzidas falsecom o ===operador.


Atualizar:

Um ponto positivo foi levantado por @Casebash nos comentários e na resposta de @Phillipe Laybaert sobre objetos. Para objetos, e ajam de forma consistente um com o outro (exceto em um caso especial).=====

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

O caso especial é quando você compara uma primitiva com um objeto que é avaliado com a mesma primitiva, devido ao seu toStringou valueOfmétodo. Por exemplo, considere a comparação de uma primitiva de string com um objeto de string criado usando o Stringconstrutor.

"abc" == new String("abc")    // true
"abc" === new String("abc")   // false

Aqui o ==operador está verificando os valores dos dois objetos e retornando true, mas ===está vendo que eles não são do mesmo tipo e estão retornando false. Qual deles está correto? Isso realmente depende do que você está tentando comparar. Meu conselho é ignorar completamente a questão e simplesmente não usar o Stringconstrutor para criar objetos de string a partir de literais de string.

Referência
http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3

Bill the Lizard
fonte
237
=== não é mais rápido se os tipos forem iguais. Se os tipos não forem os mesmos, === será mais rápido, pois não tentará fazer a conversão.
Bill o Lagarto
521
=== nunca será mais lento que ==. Ambos fazem verificação de tipo, portanto === não faz nada a mais em comparação com ==, mas a verificação de tipo pode permitir que === saia mais cedo quando os tipos não forem os mesmos.
Bill o lagarto
246
Substituir tudo == /! = Por === /! == aumenta o tamanho do arquivo js, ​​e levará mais tempo para carregar. :)
Marco Demaio 31/03
92
"... as regras pelas quais eles que são complicadas e unmemorable ..." Agora essas declarações fazem você se sentir tão seguro quando a programação ...
Johan
47
De Crockford: "A falta de transitividade é alarmante". Se você desenvolver software e não achar alarmante a falta de transitividade em um operador de comparação, ou se a comparação de velocidade entre == e === ou o tamanho do arquivo / tempo de carregamento tiver precedência sobre o determinismo transitivo do comportamento de um operador de comparação, você pode ser necessário voltar e começar de novo.
Jinglesthula 29/05
1144

Usando o ==operador ( Igualdade )

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 ==digita coerção , o que significa que o intérprete 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 e, portanto, é mais rápido (conforme o teste de benchmark This JS ), pois pula uma etapa.

Kalpesh Rajai
fonte
9
@Software Monkey: não para tipos de valor (número, booleano, ...)
Philippe Leybaert
34
Uma vez que ninguém tenha mencionado a Igualdade Tabela Javascript, aqui está: dorey.github.io/JavaScript-Equality-Table
chama
6
Na primeira declaração, você tem certeza de que 'true' é convertido em 1 e não 1 convertido em true?
Shadi Namrouti
2
De onde vêm os termos "igualdade" e "identidade"? O padrão não usa esses termos. Chama =="igualdade abstrata" e ==="igualdade estrita". Concedido chamar ==qualquer tipo de "igualdade" é IMHO horrível, uma vez que não é transitivo, mas por que reclamar? Eu levo mais problemas com a "identidade"; Eu acho que esse termo é bastante enganador, embora "funcione". Mas, falando sério, quem cunhou o termo "identidade"? Eu procuro o padrão e não o encontrei.
Ray Toal
1
"Identidade" é muito a palavra errada. Comparações de identidade em todas as linguagens que usei significa uma no mesmo objeto , ou seja, as duas variáveis ​​de referência estão apontando não apenas para entidades equivalentes, mas para a mesma entidade.
Inigo
724

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

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


var1 === var2

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

Avaliação da igualdade de === em JS


var1 == var2

Ao usar ==para testes de igualdade de JavaScript, ocorrem algumas conversões descoladas.

Avaliação da igualdade de == em JS

Moral da história:

Use a ===menos que você entenda completamente as conversões que ocorrem ==.

SNag
fonte
3
@ mfeineé você quer dizer === ou! == em vez de == ou! =. Não quero confundir novos codificadores;)
katalin_2003
2
da minha experiência usando três iguais pode causar problemas e deve ser evitado, a menos que seja totalmente compreendido. dois iguais produz resultados muito melhores porque 99% das vezes eu realmente não quero que os tipos sejam iguais.
vsync 12/02
13
@vsync: Se você realmente não quer tipos para ser igual , você deve usar três iguais !
Senão
7
A única exceção: você pode usar x == nullcom segurança para verificar se xé nullou undefined.
Andy Andy
1
@ user648026: A pergunta é sobre a igualdade comparação com ==vs ===. As maiúsculas e minúsculas são desiguais de qualquer maneira e retornam falsecom ambos ==e ===operadores. Além disso, as palavras-chave true, false, undefined, null, Infinityexistir em JS em apenas um caso, e não pode ser utilizado em casos superiores ou mistos.
SNag 06/03/19
609

Nas respostas aqui, eu não li nada sobre o que significa igual . Alguns dirão que isso ===significa igual e do mesmo tipo , mas isso não é verdade. Na verdade, significa que os dois operandos referenciam o mesmo objeto ou, no caso de tipos de valor, têm 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é:

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. A história tem mais do que ser igual e ser do mesmo tipo.

A regra é:

Para tipos de valores (números):
a === b retorna true seaebtiver o mesmo valor e for do mesmo tipo

Para tipos de referência:
a === b retorna true seae fazbreferência exatamente ao mesmo objeto

Para strings:
a === b retorna true seaebsão ambas strings e contêm exatamente os mesmos caracteres


Strings: o caso especial ...

As strings não são tipos de valor, mas em Javascript se comportam como tipos de valor, portanto serão "iguais" quando os caracteres na string forem iguais e quando tiverem o mesmo comprimento (conforme explicado na terceira regra)

Agora isso se torna 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 seqüências de caracteres se comportam como tipos de valor? Bem, depende de quem você pergunta ... Nesse caso, aeb não são do mesmo tipo. aé do tipo Object, enquanto bé do tipo string. Lembre-se de que a criação de um objeto de string usando o Stringconstrutor cria algo do tipo Objectque se comporta como uma string na maioria das vezes .

Philippe Leybaert
fonte
6
ativa: Eu esclareceria que as strings são iguais apenas quando são literais. new String ("abc") === "abc" é falso (de acordo com minha pesquisa).
Lawrence Dol
3
new Number() == "0". Também no Firefox:(function(){}) == "function () {\n}"
Thomas Eding
3
Obrigado por explicar o porquê new String("123") !== "123". Eles são tipos diferentes. Simples, mas confuso.
Styfle
21
Stringobjetos se comportam como cadeias de caracteres como qualquer outro objeto . new Stringnunca deve ser usado, pois isso não cria strings reais. Uma string real e pode ser feita com literais de string ou chamando Stringcomo uma função sem new , por exemplo:String(0); //"0", Real string, not an object
Esailija
6
Mas nos casos detalhados, o operador "==" se comporta exatamente da mesma maneira.
Yaron Levi
270

Deixe-me adicionar este conselho:

Em caso de dúvida, leia a especificação !

ECMA-262 é a especificação para uma linguagem de script da qual o JavaScript é um dialeto. Obviamente, 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 por que a nova String ("a")! == "a" .

Deixe-me explicar como ler a especificação para esclarecer esta questão. Vejo que, neste tópico muito antigo, ninguém teve uma resposta para o efeito muito estranho. Portanto, se você pode ler uma especificação, isso o ajudará tremendamente em sua profissão. É uma habilidade adquirida. Então, vamos continuar.

Pesquisando === no arquivo PDF, chego à página 56 da especificação: 11.9.4. O operador Strict Equals (===) e, depois de percorrer as instruções específicas, encontro:

11.9.6 O algoritmo de comparação estrita de igualdade
A comparação x === y, onde xey são valores, produz verdadeiro ou falso . Essa comparação é realizada da seguinte maneira:
  1. Se o Tipo (x) for diferente do Tipo (y), retorne false .
  2. Se o Tipo (x) for Indefinido, retorne verdadeiro .
  3. Se o Tipo (x) for Nulo, retorne verdadeiro .
  4. Se o Tipo (x) não for Número, vá para a etapa 11.
  5. Se x for NaN , retorne falso .
  6. Se y for NaN , retorne false .
  7. Se x é o mesmo valor numérico que y, retorne true .
  8. Se x é +0 e y é −0, retorne verdadeiro .
  9. Se x é −0 e y é +0, retorne true .
  10. Retorne falso .
  11. Se Type (x) for String, retorne true se xey forem exatamente a mesma sequência de caracteres (mesmo comprimento e mesmos caracteres nas posições correspondentes); caso contrário, retorne false .
  12. Se o Tipo (x) for Booleano, retorne true se xey forem verdadeiros ou ambos falsos ; caso contrário, retorne false .
  13. Return truese x e y se referirem ao mesmo objeto ou se eles se referem a objetos unidos um ao outro (consulte 13.1.2). Caso contrário, retorne false .

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

Não tão rápido!

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

Se você se pergunta por que a nova String ("a") não retorna uma string, que tal um exercício de leitura de uma especificação? Diverta-se!


Aidiakapi escreveu isso 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 construtores String . E ai! A semântica de valor para seqüências de caracteres (consulte a etapa 11) é perdida.

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

nalply
fonte
O resultado do tipo (x) está implícito como sendo o mesmo do tipo?
Dfr 15/11
@nalply Eu não entendo exatamente a ansiedade com relação ao comportamento new String('x'), porque nunca vi nenhum código na natureza que use objetos wrapper primitivos, e acho que não há muitas boas razões para isso, principalmente hoje em dia. Você já encontrou um código que faz isso?
Andy
@Andy o problema é malicioso ou apenas código de terceiros desleixado, então você não pode assumir que ninguém o usa new String().
precisa saber é
Se estiver desleixado, === é como você descobrirá. Se é malicioso, acho que new String()é provavelmente a menor das suas preocupações. Entendo a preocupação em teoria, mas, novamente, você tem exemplos do mundo real? Para mim, é como a velha ansiedade que alguém poderia definir undefinedcom outro valor.
Andy
Não sei onde você conseguiu isso, mas seu algoritmo de comparação está errado na etapa 2. A seção "7.2.15 Comparação estrita de igualdade" primeiro verifica se os tipos são os mesmos, se sim, se eles são Number. Caso contrário, a seção "7.2.12 SameValueNonNumber (x, y)" é usada.
Rusty Core
101

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

Shiki
fonte
10
@ David: correto. É por isso que esta resposta é imprecisa (ou mesmo errado)
Philippe Leybaert
7
@ David var a = {}, b = {}; a == bretorna falso.
nyuszika7h
6
Sim: Dois objetos diferentes com o mesmo tipo e valor comparam false, ou seja, esta resposta está errada. Por que ele tem 50 votos positivos?
Alexis
4
Sei que isso é antigo, mas esclarecer por que essa resposta ainda é "correta" é porque, no exemplo, var a = {}, b = {};Embora ambos ae de bfato ambos sejam um objeto, mas eles não têm o mesmo valor, tecnicamente falando. São instâncias diferentes . Observe que a comparação de instâncias se comporta de maneira diferente da comparação de primitivas. O que provavelmente aumenta essa confusão. Você verá um comportamento de comparação semelhante se usar a versão da instância dos tipos de dados primitivos. Por exemplo, new String('asdf')ou new Number(5). Ex: new Number(5) == new Number(5)é falso, mesmo que eles possuam o mesmo valor.
Norman Breau
1
Todos nós esquecemos que uma referência a um objeto é na verdade um Tipo de Valor, pois é um ponteiro para um slot de memória. A comparação de objetos não está comparando o "valor do objeto", mas se os dois ponteiros são iguais, o que significa que eles fazem referência ao mesmo slot de memória. Essa é uma diferença muito sutil na comparação de tipos, pois o operador "===" realmente precisa dizer "se tipo, valor e referência ao objeto na memória são os mesmos".
Stokely
101

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 com média):

==: 115.2
===: 114.4

Então, eu diria que a diferença minúscula (são mais de 100000 iterações, lembre-se) é insignificante. O desempenho não é uma razão para fazer ===. Digite safety (bem, o mais seguro que você conseguir em JavaScript) e a qualidade do código é.

Simon Scarfe
fonte
3
Mais do que o tipo de segurança, você deseja uma correção lógica - às vezes você quer que as coisas sejam verdadeiras quando ==discordam.
precisa saber é o seguinte
4
Agora, como eles se comparam quando existe uma coerção de tipo real para o ==operador? Lembre-se, é aí que há um aumento no desempenho.
Hubert OG
2
Diferença MAIOR quando testada corretamente pelos motivos acima mencionados, mais rapidamente para verificar apenas a desigualdade de tipo. jsfiddle.net/4jhuxkb2
Doug Morrow
Você mede o desempenho de algo parecido com isto em operações / segundo, não um único teste em um único navegador (um com cerca de 5% de participação de mercado) usando console.time () enquanto usa um teste que não exige coerção de tipo (o motivo todo é mais lento) em consideração. Este é um teste completamente sem sentido. Você está certo de que o desempenho não é o motivo do uso ===excessivo, ==mas está errado que o desempenho deles seja essencialmente igual e que você pensaria que esse teste prova que, e que muitas outras pessoas concordaram, é totalmente absurdo para mim.
Stephen M Irving
97

Em JavaScript, significa o mesmo valor e tipo.

Por exemplo,

4 == "4" // will return true

mas

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

O === operador é chamado um operador de comparação estrita, que não diferem do == operador.

Vamos pegar 2 vars a e b.

Para "a == b" avaliar como verdadeiro aeb precisa ser o mesmo valor .

No caso de "a === b" a e b devem ter o mesmo valor e também o mesmo tipo para que seja avaliado como verdadeiro.

Veja o exemplo a seguir

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 ; o uso do operador == pode ser avaliado como verdadeiro em situações nas quais você não deseja, usando o === operador seria mais seguro.

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

Doctor Jones
fonte
82

Por quê == é tão imprevisível?

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

true

Sim, está certo de acordo com == uma string vazia e o número zero é ao mesmo tempo.

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

'0' == false // true

As coisas ficam realmente 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 este é apenas o material maluco que você recebe com os primitivos.

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

Neste ponto, você provavelmente está se perguntando ...

Por que isso acontece?

Bem, é porque, ao contrário de "triple equals" ( ===), apenas verifica se dois valores são iguais.

==faz um monte de outras coisas .

Possui tratamento especial para funções, tratamento especial para nulos, indefinidos, cadeias, o nome dele.

Fica muito maluco.

De fato, se você tentasse escrever uma função que faça o ==que seria, 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 == é complicado.

Por ser complicado, é difícil saber o que acontecerá quando você o usar.

O que significa que você pode acabar com bugs.

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

Torne sua vida menos complicada.

Use em ===vez de ==.

O fim.

Luis Perez
fonte
Você looseEqualestá errado. Function == Function.toString()é verdade, mas looseEqual(Function, Function.toString())é falsa. Não sei por que você filtra as funções no início.
Oriol
@ Oriol, você estava certo, eu atualizei o código para explicar isso. Para os seus testes, não bastava remover o filtro para "funções", ao invés disso, "funções" tinham que ser tratadas de maneira diferente.
22616 Luis Perez
Esteja ciente de que a especificação não trata as funções de maneira diferente, elas são apenas objetos. O problema parece que você confia typeof x === "object"para verificar se é um objeto, mas `typeof só funciona para primitivas não nulas. Você pode estar interessado na minha lista de formas adequadas para verificar se um valor é um objeto
Oriol
Tentei tratar funções e objetos da mesma forma, mas achei que os resultados estavam incorretos. Por exemplo, se funções foram tratadas como objetos, a comparação de uma função com um objeto que implementa a função valueOf () ou toString () que corresponde à função passaria, mas, na realidade, não é. Exemplo: (function blah() { console.log("test"); }) != {valueOf:function(){return "function blah() { console.log(\"test\"); }";}}- verificação para este JS violino que executa todos os testes: jsfiddle.net/luisperezphd/7k6gcn6g (há 1.225 permutações de teste)
Luis Perez
1
Você está certo, ótimas observações, isso enfatiza o ponto principal que ==faz muitas coisas, dificultando a antecipação dos resultados, embora ===seja muito mais direto e previsível, sendo uma das principais razões ===a escolha recomendada. (Vou acrescentar uma nota para a resposta mencionando o seu ponto)
Luis Perez
81

===verifica que os mesmos lados têm o mesmo 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

Muitas vezes um untyped cheque seria útil porque você não se importa se o valor é ou undefined, null, 0 ou""

vsync
fonte
7
também,'string' !== 'number'
Homer
72

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

Igualdade estrita de Javascript

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

Não igualdade de Javascript

Samar Panda
fonte
Não entendo por que a stringseta está apontando para a grande caixa cinza; isso significa que o interruptor está convertendo a string em um número?
vsync 11/02
@vsync Aponta para a opção de string dentro da caixa cinza, isto é, string -> # || NaN. Javascript não é uma linguagem de script de tipo, ou seja, basicamente, pode ter qualquer tipo de variável. Então, está apontado para essa caixa cinza.
Samar Panda
Eu simplesmente perguntei se é para fins de conversão, já que o valor stringdeve ser comparado a um tipo number, de modo que o interruptor analisa o que a string deve ser comparada e a projeta adequadamente.
vsync 12/02
1
A grande caixa cinza é o ToNumberque retornaria quando eram fornecidos tipos diferentes; portanto, se receber uma sequência, ela escolherá apenas a última opção (e a converterá em um número). ==usa ToNumbersomente nos casos string == numberou boolean == anythingacima (e somente no string/ boolean). Isso significa ==que nunca será convertido undefinedou nullmesmo que eles estejam na caixa cinza. (Para qualquer combinação de um undefinedou de nullambos, ==sempre retornará true. Além disso, se um valor está no lado esquerdo ou direito não importa, ==(e ===) retornará o mesmo resultado.)
user2033427
55

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
Anik Islam Abhi
fonte
54

Significa igualdade sem coerção de tipo coerção de tipo significa que o JavaScript não converte automaticamente outros tipos de dados em tipos de dados de cadeia

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 
Pop Catalin
fonte
48

Em um script típico, não haverá diferença de desempenho. Mais importante pode ser o fato de mil "===" serem 1 KB mais pesados ​​que mil "==" :) Os criadores de perfil JavaScript podem dizer se existe uma diferença de desempenho no seu caso.

Mas, pessoalmente, eu faria o que JSLint sugere. Essa recomendação existe não por causa de problemas de desempenho, mas porque o meio de coerção de tipo ('\t\r\n' == 0)é verdadeiro.

Constantin
fonte
4
Nem sempre é verdade. Com a compactação gzip, a diferença seria quase insignificante.
Daniel X Moore
1
Concordo, mas mil "===" também significa 10 milhares de linhas de código lugar tão 1kb mais ou menos ...;)
Jonny
f o que preocupado com o tamanho, em seguida, apenas trocar todo o seu == com ===, em seguida, usar uma expressão regular envolto em eval av para ligá-lo de volta
46

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

Se você precisa viver com ele, lembre-se das três coisas a seguir:

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

TABELA DA VERDADE DO OPERADOR IGUAL NO JAVASCRIPT

  • Cada linha da tabela é um conjunto de 3 valores "iguais" mutuamente, o que significa que quaisquer 2 valores entre eles são iguais usando o sinal de 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.
CuongHuyTo
fonte
39

É improvável que haja qualquer diferença de desempenho entre as duas operações em 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.

Sean
fonte
38

Sim! Isto é importante.

===O operador em javascript verifica o valor e o tipo where, como o ==operador apenas verifica o valor (digita a conversão, se necessário) .

insira a descrição da imagem aqui

Você pode testá-lo facilmente. 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ê receberá ' false ' em alerta. Agora modifique o onPageLoad()método para que alert(x == 5);você se torne verdadeiro .

Aniket Thakur
fonte
33

=== O operador verifica os valores e os tipos das variáveis ​​quanto à igualdade.

== O operador apenas verifica o valor das variáveis ​​quanto à igualdade.

Niraj CHoubey
fonte
32

É um teste estrito de verificação.

É uma coisa boa, especialmente se você estiver verificando entre 0 e falso e nulo.

Por exemplo, se você tiver:

$a = 0;

Então:

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

Tudo retorna verdadeiro e você pode não querer isso. Vamos supor que você tenha uma função que pode retornar o 0º índice de uma matriz ou falhar em caso de falha. Se você marcar com "==" false, poderá obter um resultado confuso.

Portanto, com a mesma coisa que acima, mas com um teste rigoroso:

$a = 0;

$a===0; // returns true
$a===NULL; // returns false
$a===false; // returns false
Daniel
fonte
3
Em JavaScript, isso está completamente errado e incorretamente incompleto. 0 != null. -1
Ry-
31

O JSLint às vezes fornece razões irrealistas para modificar coisas. ===tem exatamente o mesmo desempenho que== se os tipos já fossem os mesmos.

É mais rápido apenas quando os tipos não são os mesmos; nesse caso, ele não tenta converter tipos, mas retorna diretamente um false.

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

Ou seja, não há razão para mudar ==para ===em uma verificação comoif (a == 'test') quando você a conhece pelo fato de que a pode ser apenas uma String.

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

cinzas
fonte
30

Simplesmente

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

&

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

Conversão de tipo em javaScript significa que o javaScript converte automaticamente quaisquer outros tipos de dados em tipos 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 
Amit
fonte
26

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.
Vikas
fonte
25

As 2 principais respostas mencionadas == significa igualdade e === significa identidade. Infelizmente, esta afirmação está incorreta.

Se os dois operandos de == forem objetos, eles serão comparados para ver se são o mesmo objeto. Se os dois operandos apontarem para o mesmo objeto, o operador igual retornará verdadeiro. Caso contrário, os dois não são iguais.

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

No código acima, ambos == e === ficam falsos porque aeb não são os mesmos objetos.

Ou seja: se ambos os operandos de == são objetos, == se comporta da mesma forma que ===, o que também significa identidade. A diferença essencial desses dois operadores é sobre conversão de tipos. == tem conversão antes de verificar a igualdade, mas === não.

Harry He
fonte
24

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

Os motivos são explicados 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 JSHint ainda fornece a eqnullopção relaxante por esse motivo.

No guia de estilo do jQuery :

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

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

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

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

O que logo se torna um problema. O melhor exemplo de por que a conversão implícita é "maligna" pode ser obtido desse código no MFC / C ++, que na verdade será compilado devido a uma conversão implícita de CString em HANDLE, que é um tipo de tipo de ponteiro ...

CString x;
delete x;

O que obviamente durante o tempo de execução faz muito coisas indefinidas ...

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

Thomas Hansen
fonte
2
0 == nullé falso.
21414 Garrett
21

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 os dois operandos forem iguais e do mesmo tipo. Geralmente é melhor e mais seguro se você comparar dessa maneira, porque não há conversões de tipo nos bastidores.

>>> 1 === '1'
false
>>> 1 === 1
true
user2601995
fonte
20

Aqui está uma tabela de comparação prática que mostra as conversões que acontecem e as diferenças entre ==e ===.

Como afirma a conclusão:

"Use três iguais, a menos que você entenda completamente as conversões que ocorrem para dois iguais".

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

Christian Hagelid
fonte
20

nulo e indefinido são o nada, isto é,

var a;
var b = null;

Aqui ae bnão tem valores. Considerando que 0, false e '' são todos valores. Uma coisa comum entre todos esses é que todos são valores falsificados, o que significa que todos satisfazem condições falsas.

Portanto, 0, false e '' juntos formam um subgrupo. E por outro lado, nulo e indefinido formam o segundo subgrupo. Verifique as comparações na imagem abaixo. nulo e indefinido seriam iguais. Os outros três seriam iguais. Mas todos eles são tratados como condições falsas no JavaScript.

Digite a descrição da imagem aqui

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

vivek_nk
fonte