¿Qué operador igual (== vs ===) debe usarse en las comparaciones de JavaScript?

5665

Estoy usando JSLint para pasar por JavaScript, y está devolviendo muchas sugerencias para reemplazar ==(dos signos iguales) con ===(tres signos iguales) al hacer cosas como comparar idSele_UNVEHtype.value.length == 0dentro de una ifdeclaración.

¿Hay una ventaja de rendimiento a reemplazar ==con ===?

Cualquier mejora en el rendimiento sería bienvenida ya que existen muchos operadores de comparación.

Si no se lleva a cabo una conversión de tipo, ¿se produciría un aumento de rendimiento ==?

bcasp
fuente
134
Para quienes puedan estar interesados ​​en el mismo tema === vs ==, pero en PHP, puede leer aquí: stackoverflow.com/questions/2401478/why-is-faster-than-in-php/…
Marco Demaio
257
Por si alguien se lo preguntaba en 2012: ===es mucho más rápido que ==. jsperf.com/comparison-of-comparisons
Ry-
25
@minitech debería ser, ya que no hace conversión de tipo
Umur Kontacı
19
@minitech, dudo que alguien haga que su aplicación sea notablemente más rápida al usar ===over ==. De hecho, el punto de referencia no muestra una gran diferencia entre ambos en los navegadores modernos. Personalmente, suelo usarlo en ==todas partes a menos que realmente necesite una igualdad estricta.
Laurent
55
Aquí está la parte de la charla de JS The Good Parts de Crockford donde discute los operadores ===y ==: youtube.com/… Si no funciona, es a las 15:20
davidhiggins

Respuestas:

6486

El operador de igualdad estricta ( ===) se comporta de manera idéntica al operador de igualdad abstracto (== ), excepto que no se realiza una conversión de tipo, y los tipos deben ser los mismos para ser considerados iguales.

Referencia: Tutorial de Javascript: Operadores de comparación

El ==operador comparará la igualdad después de realizar las conversiones de tipo necesarias . El ===operador no realizará la conversión, por lo que si dos valores no son del mismo tipo ===, simplemente regresará 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 cabría esperar. Si los dos operandos son del mismo tipo y tienen el mismo valor, entonces ===produce truey !==produce false. 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 cuales hacen eso son complicadas e inmemorables. 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

Tabla de comparación de igualdad

La falta de transitividad es alarmante. Mi consejo es que nunca uses a los gemelos malvados. En cambio, siempre use ===y !==. Todas las comparaciones que acabamos de mostrar producen falsecon el ===operador.


Actualizar:

@Casebash trajo un buen punto en los comentarios y en la respuesta de @Phillipe Laybaert sobre los objetos. Para objetos, ==y ===actuar consistentemente 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 una primitiva con un objeto que se evalúa en el mismo primitivo, debido a su toStringo valueOfmétodo. Por ejemplo, considere la comparación de una primitiva de cadena con un objeto de cadena creado usando el Stringconstructor.

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

Aquí el ==operador está verificando los valores de los dos objetos y regresando true, pero ===está viendo que no son del mismo tipo y regresan false. ¿Cuál es el correcto? Eso realmente depende de lo que intentes comparar. Mi consejo es evitar la pregunta por completo y simplemente no usar el Stringconstructor para crear objetos de cadena a partir de literales de cadena.

Referencia
http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3

Bill el lagarto
fuente
237
=== no es más rápido si los tipos son iguales. Si los tipos no son iguales, === será más rápido porque no intentará realizar la conversión.
Bill the Lizard
521
=== nunca será más lento que ==. Ambos realizan una verificación de tipo, por lo que === no hace nada extra en comparación con ==, pero la verificación de tipo puede permitir que === salga antes cuando los tipos no son iguales.
Bill the Lizard
246
Reemplazar todo == /! = Con === /! == aumenta el tamaño del archivo js, ​​tardará más tiempo en cargarse. :)
Marco Demaio
92
"... las reglas por las cuales ellos que son complicados y no tiene nada especial ..." Ahora estas declaraciones hacen sentir muy seguro cuando la programación ...
Johan
47
De Crockford: "La falta de transitividad es alarmante". Si desarrolla software y no encuentra alarmante la falta de transitividad en un operador de comparación, o si la comparación de velocidad entre == y === o el tamaño del archivo / tiempo de carga tiene prioridad en su mente sobre el determinismo transitivo del comportamiento de un operador de comparación, usted Es posible que deba regresar y comenzar de nuevo.
jinglesthula
1144

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 ==escribe la coerción , lo que significa que el intérprete intenta implícitamente convertir los valores antes de comparar.

Por otro lado, el operador de identidad ===no realiza la coerción de tipo y, por lo tanto, no convierte los valores al comparar y, por lo tanto, es más rápido (según esta prueba de referencia JS ) ya que omite un paso.

Kalpesh Rajai
fuente
99
@Software Monkey: no para tipos de valor (número, booleano, ...)
Philippe Leybaert 05 de
34
Como nadie ha mencionado la Tabla de igualdad de Javascript, aquí está: dorey.github.io/JavaScript-Equality-Table
blaze
66
En la primera declaración, ¿estás seguro de que 'verdadero' se convierte en 1 y no 1 convertido en verdadero?
Shadi Namrouti
2
¿De dónde vienen los términos "igualdad" e "identidad"? El estándar no usa esos términos. Se llama =="igualdad abstracta" y se llama ==="igualdad estricta". Por supuesto, llamar a ==cualquier tipo de "igualdad" es IMHO horrible, ya que no es transitivo, pero ¿por qué objetar? Aunque tomo más problemas con la "identidad"; Creo que ese término es bastante engañoso, aunque "funciona". Pero en serio, ¿quién acuñó el término "identidad"? Busqué el estándar y no pude encontrarlo.
Ray Toal
1
"Identidad" es, en gran medida, la palabra equivocada. Las comparaciones de identidad en todos los idiomas que he usado significan uno en el mismo objeto , es decir, las dos variables de referencia apuntan no solo a entidades equivalentes, sino a la misma entidad.
Íñigo
724

Una interesante representación pictórica de la comparación de igualdad entre ==y ===.

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


var1 === var2

Cuando se usa ===para pruebas de igualdad de JavaScript, todo es como es. Nada se convierte antes de ser evaluado.

Evaluación de igualdad de === en JS


var1 == var2

Cuando se usa ==para pruebas de igualdad de JavaScript, se producen algunas conversiones originales.

Evaluación de igualdad de == en JS

Moraleja de la historia:

Úselo a ===menos que comprenda completamente las conversiones que tienen lugar ==.

Engancharse
fuente
3
@mfeineis quiere decir === o! == en lugar de == o! =. No quiero confundir a los nuevos codificadores;)
katalin_2003
2
desde mi experiencia, usar tres iguales puede causar problemas y debe evitarse a menos que se entienda completamente. dos iguales produce resultados mucho mejores porque el 99% de las veces realmente no quiero que los tipos sean iguales.
vsync
13
@vsync: Si realmente no quieres que los tipos sean iguales , ¡ debes usar tres iguales !
SNag
77
La única excepción: puede usar x == nullcon seguridad para verificar si xes nullo undefined.
Andy
1
@ user648026: La pregunta se refiere a la igualdad frente a ==frente ===. Las mayúsculas y minúsculas son desiguales de todos modos, y volverán falsecon ambos ==y ===operadores. Además, las palabras clave true, false, undefined, null, Infinityexisten en JS sólo en un caso, y no se pueden utilizar en los casos superiores o mixtos.
SNag
609

En las respuestas aquí, no leí nada sobre lo que significa igualdad . 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 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 igual y ser del mismo tipo.

La regla es:

Para los tipos de valor (números):
a === b devuelve verdadero siaybtiene el mismo valor y son del mismo tipo

Para tipos de referencia:
a === b devuelve verdadero siay hacebreferencia al mismo objeto exacto

Para cadenas:
a === b devuelve verdadero siaybson ambas cadenas y contienen exactamente los mismos caracteres


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 son iguales y cuando tienen 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 cadenas se comportan como tipos de valor? Bueno, depende de a quién le pregunte ... En este caso, ayb no son del mismo tipo. aes de tipo Object, mientras que bes de tipo string. Solo recuerde que crear un objeto de cadena usando el Stringconstructor crea algo de tipo Objectque se comporta como una cadena la mayor parte del tiempo .

Philippe Leybaert
fuente
66
activa: aclararía que las cadenas son tan iguales solo cuando son literales. new String ("abc") === "abc" es falso (según mi investigación).
Lawrence Dol
3
new Number() == "0". También en Firefox:(function(){}) == "function () {\n}"
Thomas Eding
3
Gracias por explicar por qué new String("123") !== "123". Son de diferentes tipos. Simple, pero confuso.
styfle
21
StringLos objetos se comportan como cadenas como cualquier otro objeto . new Stringnunca debe usarse, ya que eso no crea cadenas reales. Una cadena real y puede hacerse con literales de cadena o llamando Stringcomo una función sin new , por ejemplo:String(0); //"0", Real string, not an object
Esailija
66
Pero en los casos que detalló, el operador "==" se comporta exactamente igual.
Yaron Levi
270

Déjame agregar este consejo:

En caso de duda, lea la especificación !

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 debe manejar algo. Pero es útil comprender por qué la nueva Cadena ("a")! == "a" .

Permítanme explicar cómo leer la especificación para aclarar esta pregunta. Veo que en este tema tan antiguo nadie tenía una respuesta para el efecto muy extraño. Entonces, si puede leer una especificación, esto lo ayudará enormemente en su profesión. Es una habilidad adquirida. Entonces, continuemos.

Buscar en el archivo PDF === me lleva a la página 56 de la especificación: 11.9.4. El operador estricto igual (===) , y después de leer las especificaciones, encuentro:

11.9.6 El algoritmo estricto de comparación de igualdad
La comparación x === y, donde x e y son valores, produce verdadero o falso . Dicha comparación se realiza de la siguiente manera:
  1. Si el Tipo (x) es diferente del Tipo (y), devuelve falso .
  2. Si Tipo (x) no está definido, devuelve verdadero .
  3. Si Tipo (x) es Nulo, devuelve verdadero .
  4. Si Tipo (x) no es Número, vaya al paso 11.
  5. Si x es NaN , devuelva falso .
  6. Si y es NaN , devuelve falso .
  7. Si x es el mismo valor numérico que y, devuelve verdadero .
  8. Si x es +0 e y es −0, devuelve verdadero .
  9. Si x es −0 e y es +0, devuelve verdadero .
  10. Devolver falso .
  11. Si Type (x) es String, devuelve true si xey 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 Tipo (x) es booleano, devuelve verdadero si xey son ambos verdaderos o ambos falsos ; de lo contrario, devuelve falso .
  13. Devuelve 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, regrese falso .

Interesante es el paso 11. Sí, las cadenas se tratan como tipos de valor. Pero esto no explica por qué nueva cadena ("a")! == "a" . ¿Tenemos un navegador que no cumple con ECMA-262?

¡No tan rapido!

Verifiquemos los tipos de los operandos. Pruébelo usted mismo envolviéndolos en typeof () . Encuentro que la nueva Cadena ("a") es un objeto, y se utiliza el paso 1: devuelve falso si los tipos son diferentes.

Si se pregunta por qué la nueva Cadena ("a") no devuelve una cadena, ¿qué tal un poco de ejercicio leyendo 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 Type (constructor) no es Object, lanza 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 Object, incluso para los constructores de cadenas . Y por desgracia! La semántica de valor para cadenas (consulte el paso 11) se pierde.

Y esto finalmente significa: nueva cadena ("a")! == "a" .

finalmente
fuente
¿Se supone que el resultado de Tipo (x) es el mismo que typeof?
Dfr
@nalply No entiendo exactamente la ansiedad con respecto al comportamiento new String('x'), porque nunca he visto ningún código en la naturaleza que use objetos de envoltura primitivos, y no creo que haya muchas buenas razones para hacerlo, especialmente en estos días. ¿Alguna vez has encontrado código que lo haga?
Andy
@Andy el problema es malicioso o simplemente un código de terceros descuidado, entonces no puedes asumir que nadie lo usa new String().
nalply
Si es descuidado, === es cómo lo descubrirás. Si es malicioso, creo que new String()es probablemente la menor de tus preocupaciones. Entiendo la preocupación en teoría, pero de nuevo, ¿tienes algún ejemplo del mundo real? Para mí es como la vieja ansiedad que alguien podría establecer undefineda otro valor.
Andy
No sé de dónde sacaste esto, pero tu algoritmo de comparación se equivoca en el paso 2. La sección "7.2.15 Comparación estricta de igualdad" primero comprueba si los tipos son iguales, en caso afirmativo, si son Number. De lo contrario, se utiliza la sección "7.2.12 SameValueNonNumber (x, y)".
Rusty Core
101

En PHP y JavaScript, es un operador de igualdad estricto. Lo que significa que comparará tanto el tipo como los valores.

Shiki
fuente
10
@David: correcto. Es por eso que esta respuesta es inexacta (o incluso mal)
Philippe Leybaert
77
@David var a = {}, b = {}; a == bdevuelve falso.
nyuszika7h
66
Sí: dos objetos diferentes con el mismo tipo y valor se comparan con falso, es decir, esta respuesta es simplemente incorrecta. ¿Por qué tiene 50 votos a favor?
alexis
44
Me doy cuenta de que esto es viejo, pero para aclarar por qué esta respuesta sigue siendo "correcta" es porque en el ejemplo var a = {}, b = {};Mientras ambos ay de bhecho son un objeto, pero técnicamente no tienen el mismo valor. Son instancias diferentes . Tenga en cuenta que comparar instancias se comporta de manera diferente que comparar primitivas. Lo que probablemente se suma a esta confusión. Verá un comportamiento de comparación similar si utiliza la versión de instancia de tipos de datos primitivos. Por ejemplo new String('asdf')o new Number(5). Ej: new Number(5) == new Number(5)es falso, aunque tengan el mismo valor.
Norman Breau
1
Todos olvidamos que una referencia a un objeto es en realidad un Tipo de valor, ya que es un puntero a una ranura de memoria. La comparación de objetos no compara el "valor del objeto" sino si ambos punteros son iguales, lo que significaría que hacen referencia a la misma ranura de memoria. Esa es una diferencia muy sutil al comparar Tipos, ya que el operador "===" realmente necesita decir "si el tipo, el valor y la referencia al objeto en la memoria son iguales".
Stokely
101

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

Entonces diría que la minúscula diferencia (esto es más de 100000 iteraciones, recuerde) es insignificante. El rendimiento no es una razón para hacerlo ===. Escriba seguridad (bueno, tan seguro como va a obtener en JavaScript), y la calidad del código es.

Simon Scarfe
fuente
3
Más que tipo de seguridad, desea corrección lógica: a veces quiere que las cosas sean verdaderas cuando ==no está de acuerdo.
rpjohnst
44
Ahora, ¿cómo se comparan cuando existe una coerción de tipo real para el ==operador? Recuerde, eso es cuando hay un aumento de rendimiento.
Hubert OG
2
MAYOR diferencia cuando se prueba adecuadamente por las razones antes mencionadas de comprobar más rápidamente la desigualdad de tipos. jsfiddle.net/4jhuxkb2
Doug Morrow
Usted mide el rendimiento de algo como esto en operaciones / segundo, no una sola prueba en un solo navegador (uno con aproximadamente el 5% de participación de mercado) usando console.time () mientras usa una prueba que no requiere coerción de tipo (toda la razón es más lento) en cuenta. Esta es una prueba completamente sin sentido. Tienes razón en que el rendimiento no es la razón para usar ===más, ==pero te equivocas en que su rendimiento es esencialmente igual y que crees que esta prueba demuestra que, y que muchas otras personas estuvieron de acuerdo, es totalmente absurdo para mí.
Stephen M Irving
97

En JavaScript significa del mismo valor y tipo.

Por ejemplo,

4 == "4" // will return true

pero

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

El === operador se llama un operador de comparación estricta, que no difiere de la == operador.

Tomemos 2 vars a y b.

Para que "a == b" se evalúe como verdadero a y b deben tener el 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 evaluar como verdadero en situaciones en las que no lo desee, por lo que usar el operador === sería más seguro.

En el escenario de uso del 90%, no importa cuál use, pero es útil saber la diferencia cuando algún día tiene un comportamiento inesperado.

Doctor jones
fuente
82

¿Por qué ==es tan impredecible?

¿Qué obtienes cuando comparas una cadena vacía ""con el número cero 0?

true

Sí, eso es correcto según ==una cadena vacía y el número cero es al mismo tiempo.

Y no termina ahí, aquí hay otro:

'0' == false // true

Las cosas se ponen realmente extrañas con los arreglos.

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

Luego 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 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 lo loco que obtienes con los primitivos.

Es un nivel completamente nuevo de locura cuando lo usas ==con objetos.

En este punto, probablemente te estés preguntando ...

¿Por qué pasó esto?

Bueno, es porque a diferencia de "triple igual" ( ===), que solo comprueba si dos valores son iguales.

==hace un montón de otras cosas .

Tiene un manejo especial para funciones, manejo especial para nulos, indefinidos, cadenas, lo que sea.

Se pone bastante loco.

De hecho, si intentas escribir una función que haga lo que ==hace, se vería 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 == es complicado.

Debido a que es complicado, es difícil saber qué sucederá cuando lo use.

Lo que significa que podrías terminar con errores.

Entonces la moraleja de la historia es ...

Haz tu vida menos complicada.

Usar en ===lugar de ==.

El fin.

Luis perez
fuente
Tu looseEqualestá equivocado. Function == Function.toString()Es cierto, pero looseEqual(Function, Function.toString())es falso. No estoy seguro de por qué filtra las funciones al principio.
Oriol
@Oriol tenías razón, actualicé el código para dar cuenta de eso, para tu información, según mis pruebas, no fue suficiente para eliminar el filtro de "funciones", en su lugar, las "funciones" tuvieron que ser manejadas de manera diferente.
Luis Perez
Tenga en cuenta que la especificación no trata las funciones de manera diferente, solo son objetos. El problema parece que usted confía en typeof x === "object"verificar si es un objeto, pero `typeof solo funciona para primitivas no nulas. Puede que le interese mi lista de formas adecuadas de verificar si un valor es un objeto
Oriol
Intenté tratar las funciones y los objetos de la misma manera, pero descubrí que los resultados eran incorrectos. Por ejemplo, si las funciones se trataran como objetos, la comparación de una función con un objeto que implementa la función valueOf () o toString () que coincide con la función pasaría, pero en realidad no lo hace. Ejemplo:(function blah() { console.log("test"); }) != {valueOf:function(){return "function blah() { console.log(\"test\"); }";}} echa un vistazo a este JS Fiddle que ejecuta todas las pruebas: jsfiddle.net/luisperezphd/7k6gcn6g (hay 1,225 permutaciones de prueba)
Luis Perez
1
Tiene razón, excelentes observaciones, esto enfatiza el punto principal que ==hace muchas cosas, lo que hace que sea muy difícil anticipar los resultados, mientras que ===es mucho más directo y predecible, que es una de las razones principales por ===la que se recomienda la elección. (Agregaré una nota a la respuesta mencionando su punto)
Luis Perez
81

===comprueba que 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

Muchas veces un sin tipo de verificación sería práctico porque no le importa si el valor es undefined, null, 0 o""

vsync
fuente
77
también,'string' !== 'number'
Homer
72

Diagrama de flujo de ejecución de Javascript para igualdad estricta / Comparación '==='

Javascript estricta igualdad

Diagrama de flujo de ejecución de Javascript para igualdad / comparación no estricta '=='

Javascript no igualdad

Samar Panda
fuente
No entiendo por qué la stringflecha apunta a la gran caja gris, ¿se supone que significa que el interruptor está lanzando la cadena a un número?
vsync
@vsync Apunta a la opción de cadena dentro del cuadro gris, es decir, cadena -> # || Yaya. Javascript no es un lenguaje tipo script, es decir, básicamente puede tener cualquier tipo de variable. Entonces, se apunta a esa caja gris.
Samar Panda
Simplemente pregunté si es para fines de conversión, ya que stringse supone que se compara con un tipo number, por lo que el interruptor mira con qué se debe comparar la cadena y la convierte en consecuencia.
vsync
1
El cuadro gris grande es lo ToNumberque volvería cuando se le den diferentes tipos, por lo que si se le da una cadena, solo elegirá la última opción (y la convertirá en un número). ==utiliza ToNumbersolo en los casos string == numbero boolean == anythingsuperior (y solo en string/ boolean). Esto significa ==que nunca se convertirá undefinedo nullaunque estén en el cuadro gris. (Para cualquier combinación de cualquiera undefinedo nullo ambos, ==siempre devolverá trueTambién, si un valor está en el lado izquierdo o derecho, no importa,. ==(Y ===) devolverá el mismo 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
fuente
54

Significa igualdad sin coerción de tipo coerción de tipo 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 
Pop Catalin
fuente
48

En un guión típico no habrá diferencia de rendimiento. Más importante puede ser el hecho de que mil "===" pesa 1 KB más que mil "==" :) analizadores de JavaScript pueden decirle si hay una diferencia de rendimiento en su caso.

Pero personalmente haría lo que sugiere JSLint. Esta recomendación no existe debido a problemas de rendimiento, sino porque los medios de coerción de tipo ('\t\r\n' == 0)son ciertos.

Constantin
fuente
44
No siempre es verdad. Con la compresión gzip, la diferencia sería casi insignificante.
Daniel X Moore
1
De acuerdo, pero mil "===" significa también 10 miles de líneas de código más, así que 1kb más o menos ...;)
Jonny
Si está preocupado por el tamaño, simplemente cambie todos sus == por ===, luego use una
46

El operador de comparación igual == es confuso y debe evitarse.

Si TIENES QUE vivir con eso, recuerda las siguientes 3 cosas:

  1. No es transitivo: (a == b) y (b == c) no conduce a (a == c)
  2. Se excluye mutuamente de su negación: (a == b) y (a! = B) siempre tienen valores booleanos opuestos, con todos a y b.
  3. En caso de duda, aprenda de memoria la siguiente tabla de verdad:

TABLA DE VERDAD DEL OPERADOR IGUAL EN JAVASCRIPT

  • Cada fila de la tabla es un conjunto de 3 valores mutuamente "iguales", lo que significa que 2 valores entre ellos son iguales usando 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.
CuongHuyTo
fuente
39

Es poco probable que haya alguna diferencia de rendimiento entre las dos operaciones en su uso. No hay conversión de tipo para hacer porque ambos parámetros ya son del mismo tipo. Ambas operaciones tendrán una comparación de tipos seguida de una comparación de valores.

Sean
fuente
38

¡Si! Si importa.

===El operador en javascript verifica el valor y el tipo donde el ==operador solo verifica el valor (escribe conversión si es necesario) .

ingrese la descripción de la imagen aquí

Puedes 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 onPageLoad()método para alert(x == 5);que se vuelva verdadero .

Aniket Thakur
fuente
33

=== El operador comprueba los valores, así como los tipos de variables para la igualdad.

== El operador solo comprueba el valor de las variables para la igualdad.

Niraj CHoubey
fuente
32

Es una prueba de verificación estricta.

Es algo bueno, especialmente si está comprobando entre 0 y falso y nulo.

Por ejemplo, si tienes:

$a = 0;

Entonces:

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

Todo vuelve verdadero y es posible que no desee esto. Supongamos que tiene una función que puede devolver el índice 0 de una matriz o falso en caso de falla. Si marca con "==" falso, puede obtener un resultado confuso.

Entonces, con lo mismo que el anterior, pero una prueba estricta:

$a = 0;

$a===0; // returns true
$a===NULL; // returns false
$a===false; // returns false
Daniel
fuente
3
En JavaScript, esto es completamente incorrecto e incorrectamente incompleto. 0 != null. -1
Ry-
31

JSLint a veces te da razones poco realistas para modificar cosas. ===tiene exactamente el mismo rendimiento que== si los tipos ya fueran iguales.

Es más rápido solo cuando los tipos no son iguales, en cuyo caso no intenta convertir los tipos sino que devuelve directamente un falso.

Entonces, en mi humilde opinión, JSLint puede usarse para escribir código nuevo, pero se debe evitar a toda costa la optimización excesiva inútil.

Es decir, no hay ninguna razón para cambiar ==a ===un cheque comoif (a == 'test') cuando se sabe que es un hecho que una única puede ser una cadena.

Modificar una gran cantidad de código de esa manera desperdicia el tiempo de los desarrolladores y revisores y no logra nada.

despojos mortales
fuente
30

Simplemente

==significa comparación entre operandos con type conversion

Y

===significa 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 a 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 
Amit
fuente
26

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

Las 2 respuestas principales mencionadas son == significa igualdad y === significa identidad. Lamentablemente, esta afirmación es incorrecta.

Si ambos operandos de == son objetos, entonces se comparan para ver si son el mismo objeto. Si ambos operandos apuntan al mismo objeto, 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, ambos == y === 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 tipos. == tiene conversión antes de verificar la igualdad, pero === no.

Harry He
fuente
24

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 : == nulles una forma eficiente de verificar si 'es nulo o indefinido':

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 eqnullopción relajante por este motivo.

De la guía de estilo jQuery :

Se deben usar verificaciones estrictas de igualdad (===) a favor de ==. La única excepción es cuando se comprueba si hay valores indefinidos y nulos a modo de nulo.

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

El problema es que podrías meterte fácilmente en problemas 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 de tipo puntero de definición ...

CString x;
delete x;

Lo que obviamente durante el tiempo de ejecución hace muy cosas indefinidas ...

Google para conversiones implícitas en C ++ y STL para obtener algunos de los argumentos en su contra ...

Thomas Hansen
fuente
2
0 == nullEs falso.
Garrett
21

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 se compara de esta manera, porque no hay conversiones de tipo detrás de escena.

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

Aquí hay una práctica tabla de comparación que muestra las conversiones que ocurren y las diferencias entre ==y ===.

Como dice la conclusión:

"Utilice tres iguales a menos que comprenda completamente las conversiones que tienen lugar para dos iguales".

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

Christian Hagelid
fuente
20

nulo e indefinido son la nada, es decir,

var a;
var b = null;

Aquí ay bno tienen valores. Mientras que 0, falso y '' son todos valores. Una cosa común entre todos estos 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. Verifique las comparaciones en la imagen de abajo. nulo e indefinido sería igual. Los otros tres serían iguales entre sí. Pero, todos se tratan como condiciones falsas en JavaScript.

Ingrese la descripción de la imagen aquí

Esto es lo mismo que cualquier objeto (como {}, matrices, etc.), una cadena no vacía y un valor booleano verdadero son todas condiciones verdaderas. Pero, no todos son iguales.

vivek_nk
fuente