Qual é a diferença entre ==
e ===
?
- Como exatamente a
==
comparação frouxa funciona? - Como exatamente a
===
comparação estrita funciona?
Quais seriam alguns exemplos úteis?
Qual é a diferença entre ==
e ===
?
==
comparação frouxa funciona?===
comparação estrita funciona?Quais seriam alguns exemplos úteis?
==
e===
A diferença entre o ==
operador frouxamente igual e o ===
operador estritamente idêntico é explicada exatamente no manual :
Operadores de comparação
┌────────────────────────────────────────────────────── ────────────────────────────────┐ │ Exemplo │ Nome │ Resultado │ ├────────────────────────────────────────────────────── ────────────────────────────────┤ │ $ a == $ b │ Igual │ TRUE se $ a for igual a $ b após o malabarismo do tipo. │ A $ a === $ b │ Idêntico │ TRUE se $ a for igual a $ b, e eles são do mesmo tipo. │ └────────────────────────────────────────────────────── ────────────────────────────────┘
==
Comparação fracamente igualSe você estiver usando o ==
operador, ou qualquer outro operador de comparação que faça comparações frouxas, como !=
, <>
ou ==
, você sempre precisará olhar o contexto para ver o que, onde e por que algo é convertido para entender o que está acontecendo.
Como referência e exemplo, você pode ver a tabela de comparação no manual :
Comparações frouxas com
==
┌────────────────┬──────────────────────────────────────────────── ┬───────┬──────────────┬───────┬──────────────────────────── ┬───────┐ │ UE TRUE │ FALSE │ 1 │ -1 │ "1" 0 "0" │ "-1" │ NULL │ array () │ "php" │ "" │ ├────────────────┼───────┼────────────────────────────────── ┼───────┼───────┼──────┼───────┼───────────────────────────── ┼───────┤ │ VERDADEIRO │ VERDADEIRO AL FALSO │ VERDADEIRO │ FALSO │ VERDADEIRO │ VERDADEIRO AL FALSO │ VERDADEIRO │ FALSO │ FALSO │ VERDADEIRO │ FALSO │ │ FALSO │ FALSO │ VERDADEIRO │ FALSO │ VERDADEIRO │ FALSO │ FALSO │ VERDADEIRO │ FALSO │ VERDADEIRO │ VERDADEIRO │ FALSO │ VERDADEIRO │ │ 1 │ VERDADEIRO AL FALSO │ VERDADEIRO │ FALSO │ FALSO │ VERDADEIRO AL FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ │ 0 │ FALSO │ VERDADEIRO │ FALSO │ VERDADEIRO │ FALSO │ FALSO UE VERDADEIRO │ FALSO │ VERDADEIRO AL FALSO │ VERDADEIRO │ VERDADEIRO │ │ -1 │ VERDADEIRO AL FALSO │ FALSO │ FALSO │ VERDADEIRO AL FALSO │ FALSO │ VERDADEIRO │ FALSO │ FALSO │ FALSO │ FALSO │ 1 "1" │ VERDADEIRO │ FALSO │ VERDADEIRO │ FALSO │ FALSO │ VERDADEIRO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ 0 "0" │ FALSO │ VERDADEIRO AL FALSO │ VERDADEIRO │ FALSO │ FALSO │ VERDADEIRO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ -1 "-1" │ VERDADEIRO │ FALSO │ FALSO │ FALSO │ VERDADEIRO AL FALSO │ FALSO │ VERDADEIRO │ FALSO │ FALSO │ FALSO │ FALSO │ │ NULL │ FALSO │ VERDADEIRO AL FALSO │ VERDADEIRO │ FALSO │ FALSO │ FALSO │ FALSO │ VERDADEIRO │ VERDADEIRO │ FALSO │ VERDADEIRO │ │ matriz () │ FALSO │ VERDADEIRO AL FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ VERDADEIRO │ VERDADEIRO │ FALSO │ FALSO │ Ph "php" │ VERDADEIRO │ FALSO │ FALSO │ VERDADEIRO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ VERDADEIRO │ FALSO │ │ "" │ FALSO │ VERDADEIRO │ FALSO │ VERDADEIRO │ FALSO │ FALSO │ FALSO │ FALSO │ VERDADEIRO AL FALSO │ FALSO │ VERDADEIRO │ └────────────────┴───────┴────────────────────────────────── ┴───────┴───────┴──────┴───────┴───────────────────────────── ┴───────┘
===
Comparação estrita e idênticaSe você estiver usando o ===
operador, ou qualquer outro operador de comparação que use comparação estrita como !==
ou ===
, poderá sempre ter certeza de que os tipos não serão alterados magicamente , porque não haverá conversão em andamento. Portanto, com comparação estrita, o tipo e o valor devem ser os mesmos, não apenas o valor.
Como referência e exemplo, você pode ver a tabela de comparação no manual :
Comparações rigorosas com
===
┌────────────────┬──────────────────────────────────────────────── ┬───────┬──────────────┬───────┬──────────────────────────── ┬───────┐ │ UE TRUE │ FALSE │ 1 │ -1 │ "1" 0 "0" │ "-1" │ NULL │ array () │ "php" │ "" │ ├────────────────┼───────┼────────────────────────────────── ┼───────┼───────┼──────┼───────┼───────────────────────────── ┼───────┤ │ VERDADEIRO │ VERDADEIRO AL FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ │ FALSO │ FALSO │ VERDADEIRO AL FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ │ 1 │ FALSO │ FALSO │ VERDADEIRO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ │ 0 │ FALSO │ FALSO │ FALSO │ VERDADEIRO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ │ -1 AL FALSO │ FALSO │ FALSO │ VERDADEIRO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ 1 "1" │ FALSO │ FALSO │ FALSO │ FALSO │ VERDADEIRO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ 0 "0" │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ VERDADEIRO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ -1 "-1" │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ VERDADEIRO AL FALSO │ FALSO │ FALSO │ FALSO │ │ NULL │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ VERDADEIRO │ FALSO │ FALSO │ FALSO │ │ matriz () │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ VERDADEIRO │ FALSO │ FALSO │ Ph "php" │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ VERDADEIRO │ FALSO │ │ "" │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO AL FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ VERDADEIRO │ └────────────────┴───────┴────────────────────────────────── ┴───────┴───────┴──────┴───────┴───────────────────────────── ┴───────┘
true
oufalse
. Isso é fácil de lançar. Todos os outros valores têm, para todos os efeitos práticos, combinações praticamente ilimitadas. É"five" == 5
?array(0) == 0
?array(0,0,0) == 0
?0.0000000000000000000000000000000000000000000000000001 == array()
?false
para diferentes matrizes em javascript, mastrue
para PHP desde que seus valores sejam iguais ."000" != "00"
,"000" == null
,"000" == false
,"0x0" == false
,array() == 0
,false != null
,array() != null
,false == "0x0"
,false == "000"
. Em PHP, é o comportamento oposto:"000" == "00"
,"000" != null
,"000" != false
,"0x0" != false
,array() != 0
,false == null
,array() == null
,false != "0x0"
,false != "000"
.O operador == lança entre dois tipos diferentes, se forem diferentes, enquanto o operador === realiza uma 'comparação de segurança de tipo'. Isso significa que ele só retornará true se os dois operandos tiverem o mesmo tipo e o mesmo valor.
Exemplos:
Aviso : duas instâncias da mesma classe com membros equivalentes NÃO correspondem ao
===
operador. Exemplo:fonte
Uma imagem vale mais que mil palavras:
==
Gráfico de igualdade PHP Double Equals :===
Gráfico de igualdade tripla de PHP :Código fonte para criar estas imagens:
https://github.com/sentientmachine/php_equality_charts
meditação de guru
Aqueles que desejam manter sua sanidade mental não leem mais, porque nada disso fará sentido, exceto para dizer que foi assim que o fractal de insanidade do PHP foi projetado.
NAN != NAN
masNAN == true
.==
converterá operandos esquerdo e direito em números se esquerda for um número. Então123 == "123foo"
mas"123" != "123foo"
Uma sequência hexadecimal entre aspas é ocasionalmente uma flutuação e será lançada surpresa para flutuar contra sua vontade, causando um erro de tempo de execução.
==
não é transitivo porque"0"== 0
,0 == ""
mas"0" != ""
==
."6" == " 6"
,,"4.2" == "4.20"
e"133" == "0133"
mas133 != 0133
. Mas"0x10" == "16"
e"1e3" == "1000"
expondo que a conversão corda surpresa para octal irá ocorrer tanto sem a sua instrução ou consentimento, causando um erro de execução.False == 0
,""
,[]
E"0"
.Quando os números são grandes o suficiente, eles são == Infinito.
Uma nova classe é == para 1.
Esperança:
Se você estiver usando PHP, você não usará o operador double igual, porque se você usar o triplo é igual, os únicos casos em que você deve se preocupar são NAN e números tão próximos do infinito que são convertidos no infinito. Com duplos iguais, qualquer coisa pode ser surpresa
==
para qualquer coisa ou, ou pode ser lançada contra a sua vontade e!=
para algo que obviamente deveria ser igual.Qualquer lugar que você usa
==
no PHP tem um cheiro ruim de código por causa dos 85 bugs nele expostos por regras implícitas de elenco que parecem projetadas por milhões de programadores programando por movimento browniano.fonte
Em relação ao JavaScript:
O operador === funciona da mesma forma que o operador ==, mas exige que seus operandos não tenham apenas o mesmo valor, mas também o mesmo tipo de dados.
Por exemplo, a amostra abaixo exibirá 'xey são iguais', mas não 'xey são idênticos'.
fonte
Uma adição às outras respostas relacionadas à comparação de objetos:
== compara objetos usando o nome do objeto e seus valores. Se dois objetos são do mesmo tipo e têm os mesmos valores de membro,
$a == $b
produz true.=== compara o ID interno do objeto. Mesmo se os membros forem iguais,
$a !== $b
se não forem exatamente o mesmo objeto.fonte
Em termos mais simples:
== verifica se equivalente (somente valor)
=== verifica se o mesmo (tipo valor e&) é
equivalente vs. igual : uma analogia
1 + 1 = 2 + 0 (equivalente)
1 + 1 = 1 + 1 (o mesmo)
No PHP:
true == 1 (verdadeiro - equivalente em valor)
true === 1 (false - não é o mesmo em value && type)
fonte
É tudo sobre tipos de dados. Tome um
BOOL
(verdadeiro ou falso), por exemplo:true
também é igual1
efalse
também é igual0
O
==
não se importa com os tipos de dados ao comparar: Portanto, se você tivesse uma variável que seja 1 (que também poderia sertrue
):$var=1;
E então compare com o
==
:Mas
$var
na verdade não é igualtrue
, não é? Em1
vez disso, possui o valor int , que, por sua vez, é igual a true.Com
===
, os tipos de dados são verificados para garantir que as duas variáveis / objetos / o que quer que esteja usando o mesmo tipo.Então se eu fiz
essa condição não seria verdadeira, como
$var !== true
apenas== true
(se você entende o que quero dizer).Por que você precisaria disso?
Simples - vamos dar uma olhada em uma das funções do PHP
array_search()
:A
array_search()
função simplesmente procura um valor em uma matriz e retorna a chave do elemento em que o valor foi encontrado. Se o valor não puder ser encontrado na matriz, ele retornará false . Mas, e se você fizessearray_search()
um valor armazenado no primeiro elemento da matriz (que teria a chave da matriz0
) .... aarray_search()
função retornaria 0 ... que é igual a false ..Então, se você fez:
Então, você vê como isso pode ser um problema agora?
A maioria das pessoas não usa
== false
ao verificar se uma função retorna false. Em vez disso, eles usam o!
. Mas, na verdade, é exatamente o mesmo que usar==false
, então se você fez:Portanto, para coisas assim, você usaria o em
===
vez disso, para que o tipo de dados seja verificado.fonte
Um exemplo é que um atributo do banco de dados pode ser nulo ou "":
fonte
php == é um operador de comparação que compara o valor das variáveis. Mas === compara o valor e o tipo de dados.
Por exemplo,
Nesse caso, a saída será 'Variáveis iguais', mesmo que seus tipos de dados sejam diferentes.
Mas se usarmos === em vez de ==, a saída será 'Variáveis não são iguais'. O php compara primeiro o valor da variável e depois o tipo de dados. Aqui os valores são iguais, mas os tipos de dados são diferentes.
fonte
Dado
x = 5
1) Operador: == é "igual a".
x == 8
é falso2) Operador: === é "exatamente igual a" (valor e tipo)
x === 5
é verdadeiro,x === "5"
é falsofonte
Tenha cuidado, porém. Aqui está um problema notório.
vs.
fonte
Em resumo, o === funciona da mesma maneira que o == na maioria das outras linguagens de programação.
O PHP permite que você faça comparações que realmente não fazem sentido. Exemplo:
Embora isso permita alguns "atalhos" interessantes, você deve tomar cuidado, pois uma função que retorna algo que não deveria (como "erro" em vez de um número) não será capturada e você ficará se perguntando o que aconteceu.
No PHP, == compara valores e executa conversão de tipo, se necessário (por exemplo, a cadeia "12343sdfjskfjds" se tornará "12343" em uma comparação inteira). === irá comparar o valor AND type e retornará false se o tipo não for o mesmo.
Se você olhar no manual do PHP, verá que muitas funções retornam "false" se a função falhar, mas podem retornar 0 em um cenário bem-sucedido, e é por isso que recomendam "if (function ()! == false) "para evitar erros.
fonte
Poucos exemplos
PS
vs.
fonte
Você usaria === para testar se uma função ou variável é falsa, em vez de apenas igualar a falsa (zero ou uma sequência vazia).
Nesse caso, strpos retornaria 0, o que equivaleria a falso no teste
ou
o que não é o que você quer aqui.
fonte
Quanto a quando usar um sobre o outro, considere, por exemplo, a
fwrite()
função em PHP.Esta função grava conteúdo em um fluxo de arquivos. De acordo com o PHP, "
fwrite()
retorna o número de bytes gravados, ou FALSE em erro.". Se você deseja testar se a chamada de função foi bem-sucedida, este método é defeituoso:Pode retornar zero (e é considerado bem-sucedido) e sua condição ainda é acionada. O caminho certo seria:
fonte
PHP é uma linguagem pouco tipada. O uso do operador double equal permite uma verificação solta de uma variável.
Verificar livremente um valor permitiria que alguns valores semelhantes, mas não iguais, fossem iguais:
Todos esses valores seriam iguais como iguais usando o operador double equal.
fonte
Variáveis têm um tipo e um valor.
Quando você usa essas variáveis (em PHP), às vezes você não tem o tipo bom. Por exemplo, se você fizer
O PHP precisa converter ("converter") $ var para inteiro. Nesse caso, "$ var == 1" é verdadeiro porque qualquer sequência não vazia é convertida em 1.
Ao usar ===, você verifica se o valor AND THE TYPE é igual; portanto, "$ var === 1" é falso.
Isso é útil, por exemplo, quando você tem uma função que pode retornar false (em erro) e 0 (resultado):
Esse código está errado como se
myFunction()
retornasse 0, foi convertido em false e você parece ter um erro. O código correto é:porque o teste é que o valor de retorno "é um booleano e é falso" e não "pode ser convertido em falso".
fonte
o
===
operador deve comparar a igualdade exata de conteúdo, enquanto o==
operador compararia a igualdade semântica. Em particular, ele coagirá as strings a números.A igualdade é um assunto vasto. Veja o artigo da Wikipedia sobre igualdade .
fonte
fonte
Até agora, todas as respostas ignoram um problema perigoso com ===. Foi observado de passagem, mas não estressado, que inteiro e duplo são tipos diferentes, portanto, o seguinte código:
dá:
Observe que este NÃO é um caso de "erro de arredondamento". Os dois números são exatamente iguais até o último bit, mas eles têm tipos diferentes.
Esse é um problema desagradável, porque um programa usando === pode ser executado felizmente por anos se todos os números forem pequenos o suficiente (onde "pequeno o suficiente" depende do hardware e do sistema operacional em que você está executando). No entanto, se por acaso um número inteiro for grande o suficiente para ser convertido em um dobro, seu tipo será alterado "para sempre", mesmo que uma operação subsequente, ou muitas operações, possa trazê-lo de volta para um número inteiro pequeno. E fica pior. Pode se espalhar - a infecção por duplicidade pode ser transmitida para qualquer coisa que tocar, um cálculo de cada vez.
No mundo real, é provável que isso seja um problema em programas que lidam com datas além do ano 2038, por exemplo. No momento, os carimbos de data e hora do UNIX (número de segundos desde 01-01-2009 00:00:00 UTC) exigirão mais de 32 bits; portanto, sua representação mudará "magicamente" para dobrar em alguns sistemas. Portanto, se você calcular a diferença entre duas vezes, poderá acabar com alguns segundos, mas como um dobro, em vez do resultado inteiro que ocorre no ano de 2017.
Eu acho que isso é muito pior do que conversões entre strings e números, porque é sutil. Acho fácil acompanhar o que é uma string e o que é um número, mas acompanhar o número de bits em um número está além de mim.
Portanto, nas respostas acima, existem algumas tabelas agradáveis, mas nenhuma distinção entre 1 (como número inteiro) e 1 (duplo sutil) e 1,0 (duplo óbvio). Além disso, o conselho de que você sempre deve usar === e nunca == não é ótimo, porque === às vezes falha quando o == funciona corretamente. Além disso, o JavaScript não é equivalente a esse respeito, pois possui apenas um tipo de número (internamente, pode ter diferentes representações em bits, mas não causa problemas para ===).
Meu conselho - não use nenhum. Você precisa escrever sua própria função de comparação para realmente consertar essa bagunça.
fonte
Existem duas diferenças entre
==
e===
nas matrizes e objetos PHP que acho que não foram mencionados aqui; duas matrizes com diferentes tipos de chave e objetos.Duas matrizes com diferentes tipos de chave
Se você possui uma matriz com uma classificação de chave e outra matriz com uma classificação de chave diferente, elas são estritamente diferentes (por exemplo, usando
===
). Isso pode causar se você classificar uma matriz com chave e tentar comparar a matriz classificada com a matriz original.Por exemplo, considere uma matriz vazia. Primeiro, tentamos enviar alguns novos índices para a matriz sem nenhum tipo especial. Um bom exemplo seria uma matriz com cadeias de caracteres como chaves. Agora, em um exemplo:
Agora, temos uma matriz de chaves não classificadas (por exemplo, 'ele' veio depois de 'você'). Considere a mesma matriz, mas classificamos suas chaves em ordem alfabética:
Dica : Você pode classificar uma matriz por chave usando ksort () função .
Agora você tem outra matriz com uma classificação de chave diferente da primeira. Então, vamos compará-los:
Nota : Pode ser óbvio, mas comparar duas matrizes diferentes usando sempre comparação estrita resulta
false
. No entanto, duas matrizes arbitrárias podem ser iguais usando===
ou não.Você diria: "Essa diferença é insignificante". Então eu digo que é uma diferença e deve ser considerada e pode acontecer a qualquer momento. Como mencionado acima, a classificação de chaves em uma matriz é um bom exemplo disso.
Objetos
Lembre-se de que dois objetos diferentes nunca são iguais . Esses exemplos ajudariam:
Nota : A atribuição de um objeto a outra variável não cria uma cópia; em vez disso, cria uma referência ao mesmo local de memória que o objeto. Veja aqui .
Nota : A partir do PHP7, classes anônimas foram adicionadas. A partir dos resultados, não há diferença entre
new class {}
enew stdClass()
nos testes acima.fonte