condicionales - operadores de asignacion en javascript
¿Qué operador igual(== vs===) se debe usar en las comparaciones de JavaScript? (30)
Comprueba si los mismos lados son iguales en tipo y valor .
Ejemplo:
''1'' === 1 // will return "false" because `string` is not a `number`
Ejemplo común:
0 == '''' // will be "true", but it''s very common to want this check to be "false"
Otro ejemplo común:
null == undefined // returns "true", but in most cases a distinction is necessary
Estoy usando JSLint para ir a través de JavaScript, y está devolviendo muchas sugerencias para reemplazar ==
(dos signos iguales) con ===
(tres signos iguales) al hacer cosas como comparar idSele_UNVEHtype.value.length == 0
dentro de un if
declaración.
¿Hay un beneficio de rendimiento al reemplazar ==
con ===
?
Cualquier mejora en el rendimiento sería bienvenida ya que existen muchos operadores de comparación.
Si no se realiza una conversión de tipo, ¿habría una ganancia de rendimiento superior a ==
?
El operador === se llama operador de comparación estricto, difiere del operador == .
Vamos a tomar 2 vars a y b.
Para que "a == b" se evalúe como verdadero, a y b deben ser del mismo valor .
En el caso de "a === b", a y b deben tener el mismo valor y también el mismo tipo para que se evalúe como verdadero.
Toma el siguiente ejemplo
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");
}
En resumen ; el uso del operador == podría evaluarse como verdadero en situaciones en las que no desea hacerlo, por lo que usar el operador === sería más seguro.
En el escenario de uso del 90%, no importará cuál use, pero es útil saber la diferencia cuando un día se comporta algo inesperado.
El operador de identidad ( ===
) se comporta de manera idéntica al operador de igualdad ( ==
), excepto que no se realiza una conversión de tipo, y los tipos deben ser iguales para que se los considere iguales.
Referencia: Javascript Tutorial: Operadores de comparación
El operador ==
comparará la igualdad después de hacer cualquier conversión de tipo necesaria . El operador ===
no realizará la conversión, por lo que si dos valores no son del mismo tipo ===
simplemente devolverá false
. Ambos son igualmente rápidos.
Para citar el excelente JavaScript de Douglas Crockford : The Good Parts ,
JavaScript tiene dos conjuntos de operadores de igualdad:
===
y!==
, y sus gemelos malvados==
y!=
. Los buenos funcionan de la manera que usted esperaría. Si los dos operandos son del mismo tipo y tienen el mismo valor, entonces===
producetrue
y!==
producefalse
. Los gemelos malvados hacen lo correcto cuando los operandos son del mismo tipo, pero si son de diferentes tipos, intentan forzar los valores. Las reglas por las que hacen eso son complicadas y no memorables. Estos son algunos de los casos interesantes:
'''' == ''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
La falta de transitividad es alarmante. Mi consejo es nunca usar a los gemelos malvados. En su lugar, utilice siempre
===
y!==
. Todas las comparaciones que se acaban de mostrar producenfalse
con el operador===
.
Actualizar:
@Casebash planteó un buen punto en los comentarios y en la answer @Phillipe Laybaert con respecto a los tipos de referencia. Para los tipos de referencia ==
y ===
actúan de manera coherente entre sí (excepto en un 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
El caso especial es cuando se compara un literal con un objeto que se evalúa al mismo literal, debido a su método toString
o valueOf
. Por ejemplo, considere la comparación de un literal de cadena con un objeto de cadena creado por el constructor de String
.
"abc" == new String("abc") // true
"abc" === new String("abc") // false
Aquí el operador ==
está verificando los valores de los dos objetos y devolviendo true
, pero el ===
está viendo que no son del mismo tipo y devolviendo false
. ¿Cuál es la correcta? Eso realmente depende de lo que estás tratando de comparar. Mi consejo es que omita la pregunta por completo y simplemente no use el constructor String
para crear objetos de cadena.
Referencia
http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3
En JavaScript significa del mismo valor y tipo.
Por ejemplo,
4 == "4" // will return true
pero
4 === "4" // will return false
En PHP y JavaScript, es un operador de igualdad estricta. Lo que significa, va a comparar tanto el tipo como los valores.
En las respuestas aquí, no leí nada sobre lo que significa igual . Algunos dirán que ===
significa igual y del mismo tipo , pero eso no es realmente cierto. En realidad, significa que ambos operandos hacen referencia al mismo objeto o, en el caso de los tipos de valor, tienen el mismo valor .
Entonces, tomemos el siguiente 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
Lo mismo aquí:
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
O incluso:
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
Este comportamiento no siempre es obvio. Hay más en la historia que ser iguales y ser del mismo tipo.
La regla es:
Para tipos de valor (números):
a === b
devuelve true si a
y b
tienen el mismo valor y son del mismo tipo
Para tipos de referencia:
a === b
devuelve true si a
y b
referencia al mismo objeto exacto
Para cuerdas:
a === b
devuelve true si a
y b
son ambas cadenas y contienen los mismos caracteres exactos
Cuerdas: el caso especial ...
Las cadenas no son tipos de valor, pero en Javascript se comportan como tipos de valor, por lo que serán "iguales" cuando los caracteres en la cadena sean iguales y cuando tengan la misma longitud (como se explica en la tercera regla)
Ahora se vuelve interesante:
var a = "12" + "3";
var b = "123";
alert(a === b); // returns true, because strings behave like value types
Pero ¿qué tal esto ?:
var a = new String("123");
var b = "123";
alert(a === b); // returns false !! (but they are equal and of the same type)
¿Pensé que las cuerdas se comportan como tipos de valor? Bueno, depende de a quién le preguntes ... En este caso, a y b no son del mismo tipo. a
es de tipo Object
, mientras que b
es de tipo string
. Solo recuerde que crear un objeto de cadena usando el constructor de String
crea algo de tipo Object
que se comporta como una cadena la mayor parte del tiempo .
En un script típico no habrá diferencia de rendimiento. Más importante puede ser el hecho de que mil "===" es 1 KB más pesado que mil "==" :) Los perfiladores de JavaScript pueden indicarle si hay una diferencia de rendimiento en su caso.
Pero personalmente haría lo que JSLint sugiere. Esta recomendación no se debe a problemas de rendimiento, sino porque los medios de coacción de tipo (''/t/r/n'' == 0)
son verdaderos.
Es poco probable que exista alguna diferencia de rendimiento entre las dos operaciones en su uso. No hay que realizar una conversión de tipos porque ambos parámetros ya son del mismo tipo. Ambas operaciones tendrán una comparación de tipo seguida de una comparación de valores.
Es una prueba de verificación estricta.
Es algo bueno, especialmente si está marcando entre 0 y falso y nulo.
Por ejemplo, si tiene:
$a = 0;
Entonces:
$a==0;
$a==NULL;
$a==false;
Todas las devoluciones son verdaderas y es posible que no quieras esto. Supongamos que tiene una función que puede devolver el índice 0 de una matriz o falso si falla. Si marca con "==" falso, puede obtener un resultado confuso.
Así que con lo mismo que el anterior, pero una prueba estricta:
$a = 0;
$a===0; // returns true
$a===NULL; // returns false
$a===false; // returns false
JSLint a veces te da razones poco realistas para modificar cosas. ===
tiene exactamente el mismo rendimiento que ==
si los tipos ya son iguales.
Es más rápido solo cuando los tipos no son los mismos, en cuyo caso no intenta convertir tipos, sino que devuelve directamente un falso.
Por lo tanto, IMHO, JSLint puede usarse para escribir código nuevo, pero se debe evitar a toda costa la excesiva optimización inútil.
Lo que significa que no hay razón para cambiar ==
a ===
un cheque, como if (a == ''test'')
cuando lo sabes por un hecho de que solo puede ser una Cadena.
Modificar una gran cantidad de código de esta manera desperdicia el tiempo de los desarrolladores y revisores y no logra nada.
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
Permítanme agregar este consejo:
En caso de duda, lea la specification !
ECMA-262 es la especificación para un lenguaje de script del cual JavaScript es un dialecto. Por supuesto, en la práctica importa más cómo se comportan los navegadores más importantes que una definición esotérica de cómo se supone que se maneja algo. Pero es útil entender por qué la nueva cadena ("a")! == "a" .
Permítame explicarle cómo leer la especificación para aclarar esta pregunta. Veo que en este viejo tema nadie tuvo una respuesta para el efecto muy extraño. Entonces, si puedes leer una especificación, esto te ayudará enormemente en tu profesión. Es una habilidad adquirida. Entonces, continuemos.
La búsqueda en el archivo PDF de === me lleva a la página 56 de la especificación: 11.9.4. El Operador de Igualdad Estricta (===) , y después de vadear a través de la especificación, encuentro:
11.9.6 El algoritmo de comparación de igualdad estricta
La comparación x === y, donde x e y son valores, produce verdadero o falso . Tal comparación se realiza de la siguiente manera:
1. Si el Tipo (x) es diferente del Tipo (y), devuelva falso .
2. Si el Tipo (x) no está definido, devuelva verdadero .
3. Si el Tipo (x) es Nulo, devuelva verdadero .
4. Si el Tipo (x) no es Número, vaya al paso 11.
5. Si x es NaN , devuelve falso .
6. Si y es NaN , devuelve falso .
7. Si x es el mismo valor numérico que y, devuelva verdadero .
8. Si x es +0 e y es −0, devuelve verdadero .
9. Si x es −0 e y es +0, devuelve verdadero .
10. Devuelve falso .
11. Si Tipo (x) es Cadena, entonces devuelva verdadero si x e y son exactamente la misma secuencia de caracteres (la misma longitud y los mismos caracteres en las posiciones correspondientes); de lo contrario, devuelve falso .
12. Si el Tipo (x) es Booleano, devuelve verdadero si x e y son verdaderos o ambos falsos ; de lo contrario, devuelve falso .
13. Devuelva verdadero si x e y se refieren al mismo objeto o si se refieren a objetos unidos entre sí (ver 13.1.2). De lo contrario, devuelve falso .
Interesante es el paso 11. Sí, las cadenas se tratan como tipos de valor. Pero esto no explica por qué la nueva cadena ("a")! == "a" . ¿Tenemos un navegador que no se ajusta a ECMA-262?
¡No tan rapido!
Veamos los tipos de los operandos. Pruébelo usted mismo envolviéndolos en typeof () . Encuentro que la nueva Cadena ("a") es un objeto, y se usa el paso 1: devuelva falso si los tipos son diferentes.
Si se pregunta por qué la cadena nueva ("a") no devuelve una cadena, ¿qué le parece un ejercicio de lectura de una especificación? ¡Que te diviertas!
Aidiakapi escribió esto en un comentario a continuación:
De la especificación
11.2.2 El nuevo operador :
Si el Tipo (constructor) no es Objeto, lance una excepción TypeError.
En otras palabras, si String no fuera del tipo Object, no podría usarse con el nuevo operador.
new siempre devuelve un objeto, incluso para constructores de cadenas , también. Y ay! El valor semántico de las cadenas (ver paso 11) se pierde.
Y esto finalmente significa: nueva cadena ("a")! == "a" .
Probé esto en Firefox con Firebug usando un código como este:
console.time("testEquality");
var n = 0;
while(true) {
n++;
if(n==100000)
break;
}
console.timeEnd("testEquality");
y
console.time("testTypeEquality");
var n = 0;
while(true) {
n++;
if(n===100000)
break;
}
console.timeEnd("testTypeEquality");
Mis resultados (probados cinco veces cada uno y promediados):
==: 115.2
===: 114.4
Así que diría que la diferencia minúscula (esto es más de 100000 iteraciones, recuerde) es insignificante. El rendimiento no es una razón para hacer ===
. Escriba seguridad (bueno, tan seguro como lo va a obtener en JavaScript), y la calidad del código es.
Significa igualdad sin tipo de coerción tipo de coerción significa que JavaScript no convierte automáticamente ningún otro tipo de datos a tipos de datos de cadena
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
Una representación pictórica interesante de la comparación de igualdad entre ==
y ===
.
Fuente: dorey.github.io/JavaScript-Equality-Table
var1 === var2
Cuando se usa
===
para las pruebas de igualdad de JavaScript, todo es como es. Nada se convierte antes de ser evaluado.
var1 == var2
Cuando se utiliza
==
para las pruebas de igualdad de JavaScript, se producen algunas conversiones funky.
Moraleja de la historia:
Use
===
menos que entienda completamente las conversiones que tienen lugar con==
.
Usando el operador ==
( Igualdad )
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 el operador ===
( Identidad )
true === 1; //false
"2" === 2; //false
Esto se debe a que el operador de igualdad ==
hace tipo de coerción , lo que significa que el intérprete intenta de manera implícita convertir los valores antes de comparar.
Por otro lado, el operador de identidad ===
no realiza coacción de tipo y, por lo tanto, no convierte los valores al comparar.
Comparación de igualdad:
Operador ==
Devuelve verdadero, cuando ambos operandos son iguales. Los operandos se convierten al mismo tipo antes de ser comparados.
>>> 1 == 1
true
>>> 1 == 2
false
>>> 1 == ''1''
true
Igualdad y comparación de tipos:
Operador ===
Devuelve verdadero si ambos operandos son iguales y del mismo tipo. En general, es mejor y más seguro si lo comparas de esta manera, porque no hay conversiones de tipo detrás de escena.
>>> 1 === ''1''
false
>>> 1 === 1
true
===
operador ===
comprueba los valores y los tipos de variables para la igualdad.
==
operador ==
simplemente verifica el valor de las variables para la igualdad.
El operador de comparación igual == es confuso y debe evitarse.
Si TIENE QUE vivir con eso, entonces recuerde las siguientes 3 cosas:
- No es transitiva: (a == b) y (b == c) no conduce a (a == c)
- Se excluye mutuamente a su negación: (a == b) y (a! = B) siempre tienen valores booleanos opuestos, con todos a y b.
- En caso de duda, aprenda de memoria la siguiente tabla de verdad:
MESA DE VERDAD DEL OPERADOR IGUAL EN JAVASCRIPT
- Cada fila en la tabla es un conjunto de 3 valores mutuamente "iguales", lo que significa que cualquiera de los 2 valores entre ellos son iguales utilizando el signo == igual
** EXTRAÑO: tenga en cuenta que cualquiera de los dos valores en la primera columna no son iguales en ese 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.
¡Sí! Si importa.
===
operador ===
en javascript comprueba el valor, así como el tipo donde el operador ==
simplemente verifica el valor (realiza la conversión de tipo si es necesario) .
Usted puede probarlo fácilmente. Pegue el siguiente código en un archivo HTML y ábralo en el navegador
<script>
function onPageLoad()
{
var x = "5";
var y = 5;
alert(x === 5);
};
</script>
</head>
<body onload=''onPageLoad();''>
Obtendrá '' falso '' en alerta. Ahora modifique el método onPageLoad()
para alert(x == 5);
obtendrás verdad
¿Por qué ==
es tan impredecible?
¿Qué obtienes al comparar una cadena vacía ""
con el número cero 0
?
true
Sí, eso es correcto de acuerdo con ==
una cadena vacía y el número cero es el mismo tiempo.
Y no termina ahí, aquí hay otro:
''0'' == false // true
Las cosas se ponen realmente raras con matrices.
[1] == true // true
[] == false // true
[[]] == false // true
[0] == false // true
Entonces más raro con cuerdas
[1,2,3] == ''1,2,3'' // true - REALLY?!
''/r/n/t'' == 0 // true - Come on!
Se pone peor:
¿Cuándo es igual no es 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!
Déjame decirlo de nuevo:
(A == B) && (B == C) // true
(A == C) // **FALSE**
Y esto es solo la locura que obtienes con los primitivos.
Es un nuevo nivel de locura cuando usas ==
con objetos.
En este punto tu probablemente te estás preguntando ...
¿Por qué pasó esto?
Bueno, es porque a diferencia de "triple igual" ( ===
) que solo verifica si dos valores son iguales.
==
hace un montón de otras cosas .
Tiene manejo especial para funciones, manejo especial para nulos, indefinido, cadenas, lo que sea.
Se pone bastante chiflado.
De hecho, si intentas escribir una función que haga lo que ==
hace, se vería algo así:
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();
}
Entonces, ¿qué significa esto?
Significa que ==
es complicado.
Debido a que es complicado, es difícil saber qué sucederá cuando lo uses.
Lo que significa que podría terminar con errores.
Así que la moraleja de la historia es ...
Haz tu vida menos complicada.
Utilice ===
lugar de ==
.
El fin.
El problema es que puedes tener problemas fácilmente ya que JavaScript tiene muchas conversiones implícitas, lo que significa ...
var x = 0;
var isTrue = x == null;
var isFalse = x === null;
Que muy pronto se convierte en un problema. La mejor muestra de por qué la conversión implícita es "malvada" se puede tomar de este código en MFC / C ++ que en realidad se compilará debido a una conversión implícita de CString a HANDLE, que es un tipo typedef de puntero ...
CString x;
delete x;
Lo que obviamente durante el tiempo de ejecución hace cosas muy indefinidas ...
Google para conversiones implícitas en C ++ y STL para obtener algunos de los argumentos en su contra ...
Simplemente
==
significa la comparación entre operandos con type conversion
Y
===
significa la comparación entre operandos sin type conversion
La conversión de tipos en javaScript significa que javaScript convierte automáticamente cualquier otro tipo de datos en tipos de datos de cadena.
Por ejemplo:
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
Un ejemplo simple es
2 == ''2'' -> true, values are SAME because of type conversion.
2 === ''2'' -> false, values are NOT SAME because of no type conversion.
nulo e indefinido son la nada, es decir,
var a;
var b = null;
Aquí a
y b
no tienen valores. Considerando que, 0, falso y '''' son todos los valores. Una cosa común entre todo esto es que todos son valores falsos, lo que significa que todos satisfacen condiciones falsas.
Entonces, el 0, falso y '''' juntos forman un subgrupo. Y por otro lado, nulo e indefinido forman el segundo subgrupo. Compruebe las comparaciones en la imagen de abajo. nulo e indefinido sería igual. Los otros tres serían iguales entre sí. Pero, todos ellos son tratados como condiciones falsas en JavaScript.
Esto es lo mismo que cualquier objeto (como {}, matrices, etc.), cadena no vacía y verdadero booleano son todas condiciones verdaderas Pero, no todos son iguales.
* Operadores === vs == *
1 == true => true
true == true => true
1 === true => false
true === true => true
Como regla general, generalmente usaría en ===
lugar de ==
(y en !==
lugar de !=
).
Las razones se explican en las respuestas anteriores y también Douglas Crockford lo tiene bastante claro ( JavaScript: The Good Parts ).
Sin embargo, hay una única excepción : == null
es una forma eficiente de verificar que ''es nulo o no definido'':
if( value == null ){
// value is either null or undefined
}
Por ejemplo, jQuery 1.9.1 usa este patrón 43 veces, y el verificador de sintaxis JSHint incluso proporciona la eqnull
opción relajante por esta razón.
De la guía de estilo jQuery :
Se deben utilizar controles de igualdad estrictos (===) a favor de ==. La única excepción es cuando se comprueba si está indefinido y nulo como nulo.
// Check for both undefined and null values, for some important reason. undefOrNull == null;
Desde la referencia de javascript principal
===
Devuelvetrue
si los operandos son estrictamente iguales (ver arriba) sin conversión de tipo.
Las 2 primeras respuestas mencionadas == significa igualdad y === identidad. Desafortunadamente, esta afirmación es incorrecta.
Si ambos operandos de == son objetos, se comparan para ver si son el mismo objeto. Si ambos operandos apuntan al mismo objeto, entonces el operador igual devuelve verdadero. De lo contrario, los dos no son iguales.
var a = [1, 2, 3];
var b = [1, 2, 3];
console.log(a == b) // false
console.log(a === b) // false
En el código anterior, tanto == como === se vuelven falsos porque a y b no son los mismos objetos.
Es decir: si ambos operandos de == son objetos, == se comporta igual que ===, lo que también significa identidad. La diferencia esencial de estos dos operadores es sobre la conversión de tipo. == tiene conversión antes de verificar la igualdad, pero === no lo hace.