¿Cuál es la diferencia entre ==
y ===
?
- ¿Cómo funciona exactamente la
==
comparación flexible ? - ¿Cómo funciona exactamente la
===
comparación estricta ?
¿Cuáles serían algunos ejemplos útiles?
¿Cuál es la diferencia entre ==
y ===
?
==
comparación flexible ?===
comparación estricta ?¿Cuáles serían algunos ejemplos útiles?
==
y===
La diferencia entre el ==
operador débilmente igual y el ===
operador estrictamente idéntico se explica exactamente en el manual :
Operadores de comparación
┌──────────┬───────────┬────────────────────────── ─────────────────────────────────┐ │ Ejemplo │ Nombre │ Resultado │ ├──────────┼───────────┼────────────────────────── ─────────────────────────────────┤ │ $ a == $ b │ Igual │ VERDADERO si $ a es igual a $ b después del malabarismo de tipos. │ │ $ a === $ b │ Idéntico │ VERDADERO si $ a es igual a $ b, y son del mismo tipo. │ └──────────┴───────────┴────────────────────────── ─────────────────────────────────┘
==
Comparación libremente igualSi está utilizando el ==
operador, o cualquier otro operador de comparación que utilice una comparación flexible como !=
, <>
o ==
, siempre tiene que mirar el contexto para ver qué, dónde y por qué algo se convierte para comprender lo que está sucediendo.
Como referencia y ejemplo, puede ver la tabla de comparación en el manual :
Comparaciones sueltas con
==
┌─────────┬───────┬───────┬───────┬───────┬─────── ┬───────┬───────┬───────┬───────┬─────────┬─────── ┬───────┐ │ │ VERDADERO │ FALSO │ 1 │ 0 │ -1 │ "1" │ "0" │ "-1" │ NULL │ array () │ "php" │ "" │ ├─────────┼───────┼───────┼───────┼───────┼─────── ┼───────┼───────┼───────┼───────┼─────────┼─────── ┼───────┤ │ VERDADERO │ VERDADERO │ FALSO │ VERDADERO │ FALSO │ VERDADERO │ VERDADERO │ FALSO │ VERDADERO │ FALSO │ FALSO │ VERDADERO │ FALSO │ │ FALSO │ FALSO │ VERDADERO │ FALSO │ VERDADERO │ FALSO │ FALSO │ VERDADERO │ FALSO │ VERDADERO │ VERDADERO │ FALSO │ VERDADERO │ │ 1 │ VERDADERO │ FALSO │ VERDADERO │ FALSO │ FALSO │ VERDADERO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ │ 0 │ FALSO │ VERDADERO │ FALSO │ VERDADERO │ FALSO │ FALSO │ VERDADERO │ FALSO │ VERDADERO │ FALSO │ VERDADERO │ VERDADERO │ │ -1 │ VERDADERO │ FALSO │ FALSO │ FALSO │ VERDADERO │ FALSO │ FALSO │ VERDADERO │ FALSO │ FALSO │ FALSO │ FALSO │ │ "1" │ VERDADERO │ FALSO │ VERDADERO │ FALSO │ FALSO │ VERDADERO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ │ "0" │ FALSO │ VERDADERO │ FALSO │ VERDADERO │ FALSO │ FALSO │ VERDADERO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ │ "-1" │ VERDADERO │ FALSO │ FALSO │ FALSO │ VERDADERO │ FALSO │ FALSO │ VERDADERO │ FALSO │ FALSO │ FALSO │ FALSO │ │ NULO │ FALSO │ VERDADERO │ FALSO │ VERDADERO │ FALSO │ FALSO │ FALSO │ FALSO │ VERDADERO │ VERDADERO │ FALSO │ VERDADERO │ │ array () │ FALSO │ VERDADERO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ VERDADERO │ VERDADERO │ FALSO │ FALSO │ │ "php" │ VERDADERO │ FALSO │ FALSO │ VERDADERO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ VERDADERO │ FALSO │ │ "" │ FALSO │ VERDADERO │ FALSO │ VERDADERO │ FALSO │ FALSO │ FALSO │ FALSO │ VERDADERO │ FALSO │ FALSO │ VERDADERO │ └─────────┴───────┴───────┴───────┴───────┴─────── ┴───────┴───────┴───────┴───────┴─────────┴─────── ┴───────┘
===
comparación idénticaSi está utilizando el ===
operador, o cualquier otro operador de comparación que use una comparación estricta como !==
o ===
, entonces siempre puede estar seguro de que los tipos no cambiarán mágicamente , porque no habrá conversión. Entonces, con una comparación estricta, el tipo y el valor deben ser los mismos, no solo el valor.
Como referencia y ejemplo, puede ver la tabla de comparación en el manual :
Estrictas comparaciones con
===
┌─────────┬───────┬───────┬───────┬───────┬─────── ┬───────┬───────┬───────┬───────┬─────────┬─────── ┬───────┐ │ │ VERDADERO │ FALSO │ 1 │ 0 │ -1 │ "1" │ "0" │ "-1" │ NULL │ array () │ "php" │ "" │ ├─────────┼───────┼───────┼───────┼───────┼─────── ┼───────┼───────┼───────┼───────┼─────────┼─────── ┼───────┤ │ VERDADERO │ VERDADERO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ │ FALSO │ FALSO │ VERDADERO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ │ 1 │ FALSO │ FALSO │ VERDADERO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ │ 0 │ FALSO │ FALSO │ FALSO │ VERDADERO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ │ -1 │ FALSO │ FALSO │ FALSO │ FALSO │ VERDADERO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ │ "1" │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ VERDADERO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ │ "0" │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ VERDADERO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ │ "-1" │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ VERDADERO │ FALSO │ FALSO │ FALSO │ FALSO │ │ NULO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ VERDADERO │ FALSO │ FALSO │ FALSO │ │ array () │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ VERDADERO │ FALSO │ FALSO │ │ "php" │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ VERDADERO │ FALSO │ │ "" │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ VERDADERO │ └─────────┴───────┴───────┴───────┴───────┴─────── ┴───────┴───────┴───────┴───────┴─────────┴─────── ┴───────┘
true
ofalse
. Eso es fácil de lanzar. Sin embargo, todos los demás valores tienen, a todos los efectos prácticos, combinaciones prácticamente ilimitadas. Es"five" == 5
?array(0) == 0
?array(0,0,0) == 0
?0.0000000000000000000000000000000000000000000000000001 == array()
?false
para diferentes matrices en javascript, perotrue
para PHP siempre que sus valores sean iguales ."000" != "00"
,"000" == null
,"000" == false
,"0x0" == false
,array() == 0
,false != null
,array() != null
,false == "0x0"
,false == "000"
. En PHP, que es un comportamiento contrario:"000" == "00"
,"000" != null
,"000" != false
,"0x0" != false
,array() != 0
,false == null
,array() == null
,false != "0x0"
,false != "000"
.El operador == convierte entre dos tipos diferentes si son diferentes, mientras que el operador === realiza una 'comparación segura de tipos'. Eso significa que solo devolverá verdadero si ambos operandos tienen el mismo tipo y el mismo valor.
Ejemplos:
Advertencia : dos instancias de la misma clase con miembros equivalentes NO coinciden con el
===
operador. Ejemplo:fuente
Una imagen vale mas que mil palabras:
==
Tabla de igualdad de PHP doble igual :===
Tabla de igualdad triple de PHP :Código fuente para crear estas imágenes:
https://github.com/sentientmachine/php_equality_charts
Meditación Gurú
Aquellos que desean mantener su cordura, no lean más porque nada de esto tendrá sentido, excepto para decir que así es como se diseñó la locura-fractal de PHP.
NAN != NAN
peroNAN == true
.==
convertirá los operandos izquierdo y derecho en números si left es un número. Entonces123 == "123foo"
, pero"123" != "123foo"
Una cadena hexadecimal entre comillas ocasionalmente es un flotador, y se lanzará por sorpresa flotando contra su voluntad, causando un error de tiempo de ejecución.
==
no es transitivo porque"0"== 0
, y0 == ""
pero"0" != ""
==
."6" == " 6"
`"4.2" == "4.20"
` y"133" == "0133"
pero133 != 0133
. Pero"0x10" == "16"
y"1e3" == "1000"
exponer esa conversión de cadena sorpresa a octal ocurrirá sin su instrucción o consentimiento, causando un error de tiempo de ejecución.False == 0
,""
,[]
Y"0"
.Cuando los números son lo suficientemente grandes, son == Infinito.
Una nueva clase es == a 1.
Esperanza:
Si está utilizando PHP, no utilizará el operador de doble igual porque si utiliza el triple igual, los únicos casos extremos de los que debe preocuparse son NAN y números tan cercanos al infinito que se convierten en infinito. Con dobles iguales, cualquier cosa puede sorprender
==
a cualquier cosa, o puede arrojarse por sorpresa contra su voluntad y!=
ante algo de lo que obviamente debería ser igual.Cualquier lugar que use
==
en PHP es un mal olor de código debido a los 85 errores expuestos en él por las reglas implícitas de conversión que parecen diseñadas por millones de programadores que programan por movimiento browniano.fuente
En lo que respecta a JavaScript:
El operador === funciona igual que el operador ==, pero requiere que sus operandos tengan no solo el mismo valor, sino también el mismo tipo de datos.
Por ejemplo, la muestra a continuación mostrará 'x e y son iguales', pero no 'x e y son idénticos'.
fuente
Una adición a las otras respuestas sobre la comparación de objetos:
== compara objetos usando el nombre del objeto y sus valores. Si dos objetos son del mismo tipo y tienen los mismos valores de miembro, se
$a == $b
obtiene verdadero.=== compara la identificación del objeto interno de los objetos. Incluso si los miembros son iguales,
$a !== $b
si no son exactamente el mismo objeto.fuente
En términos más simples:
== comprueba si es equivalente (solo valor)
=== comprueba si el mismo (valor & tipo)
Equivalente frente a igual: una analogía
1 + 1 = 2 + 0 (equivalente)
1 + 1 = 1 + 1 (igual)
En PHP:
verdadero == 1 (verdadero - equivalente en valor)
verdadero === 1 (falso - no es lo mismo en valor && type)
fuente
Se trata de tipos de datos. Tome un
BOOL
(verdadero o falso) por ejemplo:true
también es igual1
yfalse
también es igual0
El
==
no se preocupa por los tipos de datos al comparar: Entonces, si tuviera una variable que sea 1 (que también podría sertrue
):$var=1;
Y luego comparar con
==
:Pero en
$var
realidad no es igualtrue
, ¿verdad? Tiene el valor int de1
, que a su vez es igual a verdadero.Con
===
, los tipos de datos se verifican para asegurarse de que las dos variables / objetos / lo que sea que estén usando el mismo tipo.Entonces si lo hiciera
esa condición no sería cierta, ya
$var !== true
que solo== true
(si sabes a lo que me refiero).Por qué necesitarías esto?
Simple: echemos un vistazo a una de las funciones de PHP
array_search()
:La
array_search()
función simplemente busca un valor en una matriz y devuelve la clave del elemento en el que se encontró el valor. Si no se puede encontrar el valor en la matriz, devuelve falso . Pero, ¿ qué pasaría si hicieras unarray_search()
valor almacenado en el primer elemento de la matriz (que tendría la clave de matriz de0
...)?array_search()
función devolvería 0 ... que es igual a falso ...Entonces si lo hiciste:
Entonces, ¿ves cómo esto podría ser un problema ahora?
La mayoría de las personas no usan
== false
cuando verifican si una función devuelve falso. En cambio, usan el!
. Pero en realidad, esto es exactamente lo mismo que usar==false
, así que si lo hiciste:Entonces, para cosas como esa, usaría el
===
en su lugar, para que se verifique el tipo de datos.fuente
Un ejemplo es que un atributo de base de datos puede ser nulo o "":
fuente
php == es un operador de comparación que compara el valor de las variables. Pero === compara el valor y el tipo de datos.
Por ejemplo,
En este caso, la salida será 'Las variables son iguales', aunque sus tipos de datos sean diferentes.
Pero si usamos === en lugar de ==, la salida será 'Las variables no son iguales'. El php primero compara el valor de la variable y luego el tipo de datos. Aquí los valores son los mismos, pero los tipos de datos son diferentes.
fuente
Dado
x = 5
1) Operador: == es "igual a".
x == 8
es falso2) Operador: === es "exactamente igual a" (valor y tipo)
x === 5
es verdadero,x === "5"
es falsofuente
Pero ten cuidado. Aquí hay un problema notorio.
vs.
fuente
En resumen, === funciona de la misma manera que == en la mayoría de los otros lenguajes de programación.
PHP le permite hacer comparaciones que realmente no tienen sentido. Ejemplo:
Si bien esto permite algunos "atajos" interesantes, debe tener cuidado, ya que una función que devuelve algo que no debería (como "error" en lugar de un número) no quedará atrapada, y se preguntará qué sucedió.
En PHP, == compara valores y realiza la conversión de tipos si es necesario (por ejemplo, la cadena "12343sdfjskfjds" se convertirá en "12343" en una comparación de enteros). === comparará el valor AND type y devolverá false si el tipo no es el mismo.
Si mira el manual de PHP, verá que muchas funciones devuelven "falso" si la función falla, pero podrían devolver 0 en un escenario exitoso, por lo que recomiendan hacer "if (function ()! == falso) "para evitar errores.
fuente
Pocos ejemplos
PD
vs.
fuente
Usaría === para probar si una función o variable es falsa en lugar de simplemente equipararse a falso (cero o una cadena vacía).
En este caso, strpos devolvería 0, lo que equivaldría a falso en la prueba
o
que no es lo que quieres aquí.
fuente
En cuanto a cuándo usar uno sobre el otro, tome por ejemplo la
fwrite()
función en PHP.Esta función escribe contenido en una secuencia de archivos. Según PHP, "
fwrite()
devuelve el número de bytes escritos, o FALSO en caso de error". Si desea probar si la llamada a la función fue exitosa, este método es defectuoso:Puede devolver cero (y se considera exitoso), y su condición aún se activa. La forma correcta sería:
fuente
PHP es un lenguaje mecanografiado libremente. El uso del operador de doble igualdad permite una comprobación flexible de una variable.
Si verifica un valor de manera holgada, algunos valores similares, pero no iguales, equivalen a lo mismo:
Todos estos valores serían equivalentes como iguales utilizando el operador de doble igual.
fuente
Las variables tienen un tipo y un valor.
Cuando usa estas variables (en PHP), a veces no tiene el tipo correcto. Por ejemplo, si lo haces
PHP tiene que convertir ("emitir") $ var a entero. En este caso, "$ var == 1" es verdadero porque cualquier cadena no vacía se convierte a 1.
Al usar ===, verifica que el valor Y EL TIPO sean iguales, por lo que "$ var === 1" es falso.
Esto es útil, por ejemplo, cuando tiene una función que puede devolver falso (en caso de error) y 0 (resultado):
Este código es incorrecto, ya que
myFunction()
devuelve 0, se convierte en falso y parece tener un error. El código correcto es:porque la prueba es que el valor de retorno "es un valor booleano y es falso" y no "puede convertirse en falso".
fuente
Se
===
supone que el operador compara la igualdad de contenido exacta mientras que el==
operador compararía la igualdad semántica. En particular, obligará a las cadenas a los números.La igualdad es un tema vasto. Vea el artículo de Wikipedia sobre igualdad .
fuente
fuente
Todas las respuestas hasta ahora ignoran un problema peligroso con ===. Se ha notado de pasada, pero no se ha subrayado, que el entero y el doble son tipos diferentes, por lo que el siguiente código:
da:
Tenga en cuenta que este NO es un caso de "error de redondeo". Los dos números son exactamente iguales hasta el último bit, pero tienen diferentes tipos.
Este es un problema desagradable porque un programa que usa === puede funcionar felizmente durante años si todos los números son lo suficientemente pequeños (donde "lo suficientemente pequeño" depende del hardware y el sistema operativo en el que se está ejecutando). Sin embargo, si por casualidad, un número entero es lo suficientemente grande como para convertirse en un doble, su tipo se cambia "para siempre" a pesar de que una operación posterior, o muchas operaciones, puede devolverlo a un valor entero pequeño. Y se pone peor. Se puede propagar: la infección por duplicación puede transmitirse a cualquier cosa que toque, un cálculo a la vez.
En el mundo real, es probable que esto sea un problema en los programas que manejan fechas más allá del año 2038, por ejemplo. En este momento, las marcas de tiempo UNIX (número de segundos desde 1970-01-01 00:00:00 UTC) requerirán más de 32 bits, por lo que su representación cambiará "mágicamente" al doble en algunos sistemas. Por lo tanto, si calcula la diferencia entre dos veces, puede terminar con un par de segundos, pero como un doble, en lugar del resultado entero que ocurre en el año 2017.
Creo que esto es mucho peor que las conversiones entre cadenas y números porque es sutil. Me resulta fácil hacer un seguimiento de lo que es una cadena y lo que es un número, pero el seguimiento de la cantidad de bits en un número está más allá de mí.
Entonces, en las respuestas anteriores hay algunas tablas agradables, pero no hay distinción entre 1 (como un entero) y 1 (doble sutil) y 1.0 (doble obvio). Además, los consejos que siempre debes usar === y nunca == no son buenos porque === a veces fallará donde == funciona correctamente. Además, JavaScript no es equivalente a este respecto porque solo tiene un tipo de número (internamente puede tener diferentes representaciones de bits, pero no causa problemas para ===).
Mi consejo: no uses ninguno. Necesitas escribir tu propia función de comparación para realmente arreglar este desastre.
fuente
Hay dos diferencias entre
==
y===
en las matrices y objetos PHP que creo que no mencioné aquí; dos matrices con diferentes tipos de teclas y objetos.Dos matrices con diferentes tipos de teclas.
Si tiene una matriz con una clasificación de claves y otra matriz con una clasificación de claves diferente, son estrictamente diferentes (es decir, usando
===
). Eso puede causar si clasifica por clave una matriz e intenta comparar la matriz ordenada con la original.Por ejemplo, considere una matriz vacía. Primero, intentamos insertar algunos índices nuevos en la matriz sin ningún tipo especial. Un buen ejemplo sería una matriz con cadenas como claves. Ahora en lo profundo de un ejemplo:
Ahora, tenemos una matriz de claves no ordenadas (por ejemplo, 'él' vino después de 'usted'). Considere la misma matriz, pero clasificamos sus claves alfabéticamente:
Consejo : Puede ordenar una matriz por clave usando ksort () .
Ahora tiene otra matriz con un tipo de clave diferente de la primera. Entonces, vamos a compararlos:
Nota : Puede ser obvio, pero la comparación de dos matrices diferentes usando una comparación estricta siempre resulta
false
. Sin embargo, dos matrices arbitrarias pueden ser iguales usando===
o no.Diría: "Esta diferencia es insignificante". Entonces digo que es una diferencia y que debe considerarse y puede ocurrir en cualquier momento. Como se mencionó anteriormente, ordenar las claves en una matriz es un buen ejemplo de eso.
Objetos
Tenga en cuenta que dos objetos diferentes nunca son estrictamente iguales . Estos ejemplos ayudarían:
Nota : Asignar un objeto a otra variable no crea una copia, sino que crea una referencia a la misma ubicación de memoria que el objeto. Mira aquí .
Nota : A partir de PHP7, se agregaron clases anónimas . De los resultados, no hay diferencia entre
new class {}
ynew stdClass()
en las pruebas anteriores.fuente