Qual è il modo corretto per verificare l'uguaglianza delle stringhe in JavaScript?


844

Qual è il modo corretto per verificare la parità tra le stringhe in JavaScript?


2
C'è un motivo per non usare ==?
Kendrick,

21
@Kendrick - certo. Il suo sistema di coercizione del tipo può essere incredibilmente non intuitivo e può rendere gli errori molto facili da trascurare ( sembra giusto, ma può essere molto sbagliato)
STW

20
@Kendrick: perché restituisce {} == "[object Object]"true, ad esempio.
Chetan Sastry,

12
un po 'fastidioso che String().equals()non sia un metodo in JS ...
Alexander Mills,

2
@AlexanderMills Why?
Ry-

Risposte:


624

sempre Fino a quando non comprendi appieno le differenze e le implicazioni dell'uso deglioperatori==e===, usa l'===operatore poiché ti salverà da bug e WTF oscuri (non ovvi). L'==operatore"normale"può avere risultati molto inaspettati a causa della coercizione del tipo internamente, quindi l'utilizzo===è sempre l'approccio raccomandato.

Per avere un'idea di ciò, e altre parti "buone contro cattive" di Javascript hanno letto il signor Douglas Crockford e il suo lavoro. C'è un ottimo discorso tecnico su Google in cui riassume molte buone informazioni: http://www.youtube.com/watch?v=hQVTIJBZook


Aggiornare:

La serie You Don't Know JS di Kyle Simpson è eccellente (e gratuita da leggere online). La serie va nelle aree del linguaggio comunemente fraintese e spiega le "parti cattive" che Crockford suggerisce di evitare. Comprendendoli puoi usarli correttamente ed evitare le insidie.

Il libro " Up & Going " include una sezione sull'uguaglianza , con questo riepilogo specifico di quando utilizzare gli operatori loose ( ==) vs strict ( ===):

Per ridurre tutti i dettagli in pochi semplici passaggi e aiutarti a sapere se utilizzare ==o ===in varie situazioni, ecco le mie semplici regole:

  • Se uno dei due valori (alias lato) in un confronto potrebbe essere il valore trueo false, evitare ==e utilizzare ===.
  • Se entrambi i valori in un confronto potrebbe essere di questi valori specifici ( 0, ""o []- array vuoto), evitare ==di usare ===.
  • In tutti gli altri casi, sei sicuro da usare ==. Non solo è sicuro, ma in molti casi semplifica il codice in modo da migliorare la leggibilità.

Consiglio ancora il discorso di Crockford per gli sviluppatori che non vogliono investire il tempo per capire davvero Javascript: è un buon consiglio per uno sviluppatore che lavora solo occasionalmente in Javascript.


7
Non è necessario quando sei sicuro che entrambi gli operandi sono stringhe, ad esempio quando usiif (typeof foo == "string")
Marcel Korpel il

25
@Marcel - hai ragione, ma è molto meglio usare sempre l' ===operatore e non doversi mai preoccupare del "Sono davvero, totalmente, sicuro al 100% che ==si comporterà come penso?"
STW,

7
@STW - un esempio per cui Crockford non è l'alfa e l'omega di JavaScript, è il suo consiglio di non usare l'incremento / decremento unario ( ++/ --).
Marcel Korpel,

10
E non usare mai ++o --o if/elsedichiarazioni a riga singola o continueo l' newoperatore o qualsiasi altro numero di pratiche di codice perfettamente legittime che Crockford ha ritenuto "dannose". E ovviamente mai e poi mai nemmeno pensare di usare evalo withanche se le loro insidie ​​sono ben comprese. E hai visto la prossima versione di JS? Sintassi più rigorosa e una manciata di funzioni di supporto, alcune delle quali fluttuano da anni, è tutto ciò che otteniamo dopo tutto questo tempo. La sintassi non si è affatto evoluta. Se Crockford è dietro questo, allora è stata una brutta cosa.
MooGoo,

4
@CoffeeAddict: un test rapido in JSFiddle sembra non essere d'accordo. Sono entrambi sensibili al maiuscolo / minuscolo: jsfiddle.net/st2EU
STW

205

Se sai che sono stringhe, non è necessario controllare il tipo.

"a" == "b"

Tuttavia, si noti che gli oggetti stringa non saranno uguali.

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

restituirà false.

Chiama il metodo valueOf () per convertirlo in una primitiva per oggetti String,

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

tornerà vero


4
grazie per quel JSS, due oggetti stringa non saranno mai uguali a meno che non siano lo stesso oggetto indipendentemente dal valore.
Anurag,

4
@JSS: Inoltre, new String("a") == "a"è vero (ma non lo sarebbe ===), perché il lato sinistro verrà convertito in un valore di stringa primitivo.
Matthew Crumley,

5
@JSS: new String("a") == new String("a"), new String("a") === new String("b"), new String("a") === new String("a")tutti ritorneretefalse , dal momento che hai a che fare con i riferimenti a oggetti della Stringclasse, non primitive di tipo string.
Palswim,

4
Giusto per chiarire questo per chiunque lo legga. new String(foo)crea una stringa oggetto e String(foo) converte foo in una primitiva stringa.
Brigand,

9
@FakeRainBrigand - chiaro come fango, ma questo è ciò di cui parla javascript, vero?
Periata Breatta,

59

Solo un'aggiunta alle risposte: se tutti questi metodi restituiscono false, anche se le stringhe sembrano uguali, è possibile che ci sia uno spazio bianco a sinistra o a destra di una stringa. Quindi, basta inserire un .trim()alla fine delle stringhe prima di confrontare:

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

Ho perso ore a cercare di capire cosa c'è che non va. Spero che questo possa aiutare qualcuno!


1
Molte grazie. Però è strano per me, perché mi sono assicurato che non ci fosse spazio bianco a sinistra o a destra e comunque questo era l'unico modo per risolvere il mio problema. Forse è legato alla rappresentazione interna di una stringa?
Niko,

2
Grazie @akelec !! @Niko, probabilmente era dovuto al personaggio Zero-Width-Space che è invisibile ad occhio nudo. Vedi en.wikipedia.org/wiki/Zero-width_space . Anche se questo personaggio ha i suoi scopi, molti sviluppatori si risentono della sua esistenza!
stwr667,

Grazie, è stato frustrante dal momento che il controllo di uguaglianza nel mio se falliva, ma non ho visto spazi bianchi durante l'ispezione durante il debug.
drzounds

Un problema comune durante il caricamento di una variabile da un file di testo (ovvero: utilizzo fetch). Molte grazie.
Sopalajo de Arrierez,

@SopalajodeArrierez, esattamente, c'è principalmente uno spazio o un ritorno a capo alla fine della stringa. Prego.
akelec,

22

ciò che mi ha portato a questa domanda è il paddingewhite-spaces

controlla il mio caso

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

e il titolo era " LastName"

inserisci qui la descrizione dell'immagine

quindi forse devi usare la trimfunzione in questo modo

var title = $(this).text().trim();

2
Grazie stesso qui ho usato .toString().trim()in Typescript
Akitha_MJ

17

A meno che tu non sappia davvero come funziona la coercizione, dovresti invece evitare ==e utilizzare l'operatore di identità ===. Ma dovresti leggere questo per capire come funziona .

Se lo usi ==, lasci che la lingua faccia qualche tipo di coercizione per te, quindi ad esempio:

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

Come ha detto Douglas Crockford nel suo libro:

È sempre meglio usare l'operatore di identità.


3
Sebbene questo collegamento possa rispondere alla domanda, è meglio includere qui le parti essenziali della risposta e fornire il collegamento come riferimento. Le risposte di solo collegamento possono diventare non valide se la pagina collegata cambia.
Parkash Kumar,

{}==" "mi hai dato Unexpected token ==qual è il modo corretto di farlo?
Basheer AL-MOMANI,

12

Esistono due modi in cui è possibile creare stringhe in javascript.

  1. var str = 'Javascript'; Questo crea un valore di stringa primitivo.

  2. var obj = new String('Javascript');Questo crea un oggetto wrapper di tipo String.

    typeof str // string
    typeof obj // object

Quindi il modo migliore per verificare l'uguaglianza è usare il === operatore perché controlla sia il valore che il tipo di entrambi gli operandi.

Se si desidera verificare l'uguaglianza tra due oggetti, l'utilizzo String.prototype.valueOfè corretto.

new String('javascript').valueOf() == new String('javascript').valueOf()

6

La stringa Objectspuò essere controllata usando il JSON.stringyfy()trucco.

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


1

Considerando che entrambe le stringhe possono essere molto grandi, ci sono 2 approcci principali bitwise searchelocaleCompare

Ho raccomandato questa funzione

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

-2

Il modo più semplice per farlo è usare un operatore ternario in questo modo:

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

ma se la stringa che desideri confrontare si trova in un array, utilizzerai il filtro es6

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

quanto sopra controllerà il tuo stringArray e qualunque stringa che lo corrisponda dall'array che nel nostro caso abbiamo scelto "ragazzi"


-8

Ho trovato una soluzione alternativa durante i test. è possibile utilizzare la funzione sul prototipo di stringa.

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

funziona bene nei browser Chrome


La domanda chiede come verificare se "ciao mondo" = "ciao mondo", non come verificare se "ciao mondo" è una stringa.
Nick,

4
Questo è solo stupido. Hai creato una versione di Rube Goldberg di ==.
JJJ,

Ciao OP, la tua modifica è completamente diversa nella sua parte spirituale e la tua risposta ha già ottenuto troppi voti negativi. Vi esorto per favore a rimuovere questa risposta e a inviarne una nuova con la versione modificata
Yılmaz Durmaz
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.