¿Cuál es la forma correcta de verificar la igualdad de cadenas en JavaScript?

844

¿Cuál es la forma correcta de verificar la igualdad entre cadenas en JavaScript?

JSS
fuente
2
¿Hay alguna razón para no usar ==?
Kendrick
21
@Kendrick, claro. Su sistema de coerción de tipo puede ser increíblemente poco intuitivo y puede hacer que los errores sean muy fáciles de pasar por alto ( parece correcto, pero puede ser muy incorrecto)
STW
20
@Kendrick: porque se {} == "[object Object]"evalúa como verdadero, por ejemplo.
Chetan Sastry
12
algo molesto que String().equals()no es un método en JS ...
Alexander Mills
2
@AlexanderMills ¿Por qué?
Ry-

Respuestas:

624

siempre Hasta que comprenda completamente las diferencias e implicaciones del uso de losoperadores==y===, use el===operador ya que lo salvará de errores oscuros (no obvios) y WTF. El==operador"regular"puede tener resultados muy inesperados debido a la coerción de tipo internamente, por lo que usar===siempre es el enfoque recomendado.

Para obtener información sobre esto y otras partes "buenas contra malas" de Javascript, lea sobre el Sr. Douglas Crockford y su trabajo. Hay una gran charla técnica de Google donde resume mucha buena información: http://www.youtube.com/watch?v=hQVTIJBZook


Actualizar:

La serie You Don't Know JS de Kyle Simpson es excelente (y gratuita para leer en línea). La serie aborda las áreas comúnmente incomprendidas del lenguaje y explica las "partes malas" que Crockford sugiere que evite. Al comprenderlos, puede hacer un uso adecuado de ellos y evitar las trampas.

El libro " Up & Going " incluye una sección sobre Igualdad , con este resumen específico de cuándo usar los operadores flojos ( ==) versus estrictos ( ===):

Para resumir una gran cantidad de detalles en algunas conclusiones simples y ayudarlo a saber si usarlo ==o ===en varias situaciones, estas son mis reglas simples:

  • Si cualquiera de los valores (también conocido como lado) en una comparación podría ser el valor trueo false, evítelo ==y úselo ===.
  • Si cualquiera de los valores en una comparación podría ser de estos valores específicos ( 0, ""o []- matriz vacía), evitar el ==y uso ===.
  • En todos los demás casos, es seguro de usar ==. No solo es seguro, sino que en muchos casos simplifica su código de una manera que mejora la legibilidad.

Todavía recomiendo la charla de Crockford para desarrolladores que no quieren invertir el tiempo para comprender realmente Javascript; es un buen consejo para un desarrollador que solo ocasionalmente trabaja en Javascript.

STW
fuente
77
No es necesario cuando está seguro de que ambos operandos son una cadena, por ejemplo, cuando se usaif (typeof foo == "string")
Marcel Korpel
25
@Marcel: tienes razón, pero es mucho mejor usar siempre el ===operador y nunca tener que preocuparte por el "¿estoy realmente, totalmente seguro al 100% de que ==se comportará como creo que lo hará?"
STW
77
@STW: un ejemplo de por qué Crockford no es el alfa y omega de JavaScript, es su consejo de no usar incrementos / decrementos unarios ( ++/ --).
Marcel Korpel
10
Y nunca use ++o declaraciones de --línea única o el operador o cualquier otro número de prácticas de código perfectamente legítimas que Crockford haya considerado "dañinas". Y por supuesto, nunca jamás considerar siquiera pensar en usar o incluso si sus trampas son bien comprendidos. ¿Y has visto la próxima versión de JS? La sintaxis más estricta y un puñado de funciones auxiliares, algunas de las cuales han estado flotando durante años, es todo lo que obtenemos después de todo este tiempo. La sintaxis no ha evolucionado en absoluto. Si Crockford está detrás de esto, entonces ha sido algo malo. if/elsecontinuenewevalwith
MooGoo
44
@CoffeeAddict: una prueba rápida en JSFiddle parece estar en desacuerdo. Ambos distinguen entre mayúsculas y minúsculas: jsfiddle.net/st2EU
STW
205

Si sabe que son cadenas, no hay necesidad de verificar el tipo.

"a" == "b"

Sin embargo, tenga en cuenta que los objetos de cadena no serán iguales.

new String("a") == new String("a")

devolverá falso.

Llame al método valueOf () para convertirlo en una primitiva para objetos String,

new String("a").valueOf() == new String("a").valueOf()

volverá verdadero

Anurag
fuente
44
gracias por ese JSS, dos objetos de cadena nunca serán iguales a menos que sean el mismo objeto independientemente del valor.
Anurag
44
@JSS: Además, new String("a") == "a"es cierto (pero no lo sería ===), porque el lado izquierdo se convertirá en un valor de cadena primitivo.
Matthew Crumley
55
@JSS: new String("a") == new String("a"), new String("a") === new String("b"), new String("a") === new String("a")todos volveremos false, ya que está tratando con referencias a los objetos de la Stringclase, no primitivas de tipo string.
palswim
44
Solo para aclarar esto para cualquiera que lo lea. new String(foo)crea un objeto de cadena y String(foo) convierte foo en una cadena primitiva.
Brigante
99
@FakeRainBrigand: claro como el barro, pero de eso se tratan los javascripts, ¿no?
Periata Breatta
59

Solo una adición a las respuestas: si todos estos métodos devuelven falso, incluso si las cadenas parecen ser iguales, es posible que haya un espacio en blanco a la izquierda o derecha de una cadena. Entonces, solo ponga un .trim()al final de las cadenas antes de comparar:

if(s1.trim() === s2.trim())
{
    // your code
}

He perdido horas tratando de descubrir qué está mal. Espero que esto ayude a alguien!

akelec
fuente
1
Muchas gracias. Sin embargo, es extraño para mí, porque me aseguré de que no hubiera espacios en blanco a la izquierda o la derecha y aún así esta era la única forma de resolver mi problema. ¿Quizás está relacionado con la representación interna de una cadena?
Niko
2
Gracias @akelec !! @Niko, es probable que se deba al carácter Zero-Width-Space que es invisible a simple vista. Ver en.wikipedia.org/wiki/Zero-width_space . A pesar de que este personaje tiene sus propósitos, ¡muchos desarrolladores resienten su existencia!
stwr667
Gracias, eso fue frustrante ya que el control de igualdad en mi si fallaba, pero no vi ningún espacio en blanco al inspeccionar durante la depuración.
drzounds
Un problema común al cargar una variable desde un archivo de texto (es decir, usar fetch). Muchas gracias.
Sopalajo de Arrierez
@SopalajodeArrierez, exactamente, hay principalmente un espacio o un retorno de carro al final de la cadena. De nada.
akelec
22

lo que me llevó a esta pregunta es la paddingywhite-spaces

mira mi caso

 if (title === "LastName")
      doSomething();

y el título era " LastName"

ingrese la descripción de la imagen aquí

entonces quizás tengas que usar trimfunciones como esta

var title = $(this).text().trim();
Basheer AL-MOMANI
fuente
2
Gracias lo mismo que usé .toString().trim()en el
mecanografiado
17

A menos que realmente sepa cómo funciona la coerción, debe evitar ==y utilizar el operador de identidad en su ===lugar. Pero deberías leer esto para entender cómo funciona .

Si lo usa ==, deja que el idioma haga algún tipo de coerción por usted, por ejemplo:

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

Como Douglas Crockford dijo en su libro:

Siempre es mejor usar el operador de identidad.

ludico8
fuente
3
Si bien este enlace puede responder la pregunta, es mejor incluir aquí las partes esenciales de la respuesta y proporcionar el enlace como referencia. Las respuestas de solo enlace pueden volverse inválidas si la página vinculada cambia.
Parkash Kumar
{}==" "me dio Unexpected token ==cuál es la forma correcta de hacerlo?
Basheer AL-MOMANI
12

En realidad, hay dos formas en que las cadenas se pueden hacer en JavaScript.

  1. var str = 'Javascript'; Esto crea un valor de cadena primitivo.

  2. var obj = new String('Javascript');Esto crea un objeto contenedor de tipo String.

    typeof str // string
    typeof obj // object

Entonces, la mejor manera de verificar la igualdad es usar el ===operador porque verifica el valor y el tipo de ambos operandos.

Si desea verificar la igualdad entre dos objetos, entonces usar String.prototype.valueOfes la forma correcta.

new String('javascript').valueOf() == new String('javascript').valueOf()
Abhishek
fuente
6

La cadena Objectsse puede verificar con un JSON.stringyfy()truco.

var me = new String("me");
var you = new String("me");
var isEquel = JSON.stringify(me) === JSON.stringify(you);
console.log(isEquel);

Muhammad Usman
fuente
1

Teniendo en cuenta que ambas cadenas pueden ser muy grandes, hay 2 enfoques principales bitwise searchylocaleCompare

Recomiendo esta función

function compareLargeStrings(a,b){
    if (a.length !== b.length) {
         return false;
    }
    return a.localeCompare(b) === 0;
}
Nagibaba
fuente
-2

La forma más fácil de hacerlo es usar un operador ternario como este:

 "was" == "was" ? true : false

pero si la cadena que desea comparar está en una matriz, usará el filtro es6

let stringArray  = ["men", "boys", "girls", "sit", "can", "gotten"]
stringArray.filter(I=> I === boys ? 
stringArray.pop(indexOf(I)) : null)

lo anterior verificará su stringArray y cualquier cadena que coincida con la matriz que en nuestro caso elegimos "boys"

Pedro JR
fuente
-8

Se me ocurrió una solución alternativa durante las pruebas. puede usar la función en el prototipo de cadena.

String.prototype.betwenStr = function(one){

return JSON.stringify(new String(this)) === JSON.stringify(new String(one));

}


 //call it
 "hello world".betweenStr("hello world"); //returns boolean 
 //value

funciona bien en navegadores cromados

Khorram Bin Salim Khondkar
fuente
La pregunta pregunta cómo verificar si "hello world" = "hello world", no cómo verificar si "hello world" es una cadena.
Nick
44
Esto es una tontería. Has creado una versión de Rube Goldberg de ==.
JJJ
Hola OP, tu edición es completamente diferente en su parte espiritual, y tu respuesta ya ha recibido demasiados votos negativos. Le insto a que elimine esta respuesta y publique una nueva con su versión editada
Yılmaz Durmaz