Quelle est la bonne façon de vérifier l'égalité des chaînes en JavaScript?

844

Quelle est la bonne façon de vérifier l'égalité entre les chaînes en JavaScript?

JSS
la source
2
Y a-t-il une raison de ne pas utiliser ==?
Kendrick
21
@Kendrick - bien sûr. Son système de coercition de type peut être incroyablement peu intuitif et peut rendre les erreurs très faciles à ignorer (il semble correct, mais peut être très faux)
STW
20
@Kendrick - parce {} == "[object Object]"qu'évalué à vrai, par exemple.
Chetan Sastry
12
quelque peu ennuyeux ce String().equals()n'est pas une méthode dans JS ...
Alexander Mills
2
@AlexanderMills Pourquoi?
Ry-

Réponses:

624

toujours Jusqu'à ce que vous compreniez parfaitement les différences et les implications de l'utilisation desopérateurs==et===, utilisez l'===opérateur car il vous évitera des bugs et des WTF obscurs (non évidents). L'==opérateur"régulier"peut avoir des résultats très inattendus en raison de la coercition de type en interne, donc l'utilisation===est toujours l'approche recommandée.

Pour avoir un aperçu de cela, et d'autres parties «bonnes contre mauvaises» de Javascript lisez M. Douglas Crockford et son travail. Il y a un excellent Google Tech Talk où il résume beaucoup de bonnes informations: http://www.youtube.com/watch?v=hQVTIJBZook


Mise à jour:

La série You Don't Know JS de Kyle Simpson est excellente (et gratuite à lire en ligne). La série va dans les domaines souvent mal compris de la langue et explique les «mauvaises parties» que Crockford vous suggère d'éviter. En les comprenant, vous pouvez les utiliser correctement et éviter les pièges.

Le livre " Up & Going " comprend une section sur l' égalité , avec ce résumé spécifique de quand utiliser les opérateurs loose ( ==) vs strict ( ===):

Pour résumer un tas de détails en quelques plats à emporter simples, et vous aider à savoir s'il faut utiliser ==ou ===dans diverses situations, voici mes règles simples:

  • Si l'une des valeurs (aka côté) dans une comparaison peut être la valeur trueou false, évitez ==et utilisez ===.
  • Si l' une des valeurs dans une comparaison pourrait être de ces valeurs spécifiques ( 0, ""ou []- tableau vide), évitez ==et utilisation ===.
  • Dans tous les autres cas, vous pouvez utiliser en toute sécurité ==. Non seulement il est sûr, mais dans de nombreux cas, il simplifie votre code d'une manière qui améliore la lisibilité.

Je recommande toujours le discours de Crockford aux développeurs qui ne veulent pas investir du temps pour vraiment comprendre Javascript — c'est un bon conseil pour un développeur qui ne travaille que de manière occasionnelle en Javascript.

STW
la source
7
Ce n'est pas nécessaire lorsque vous êtes sûr que les deux opérandes sont des chaînes, par exemple lors de l'utilisationif (typeof foo == "string")
Marcel Korpel
25
@Marcel - vous avez raison, mais il vaut beaucoup mieux de toujours utiliser l' ===opérateur et de ne jamais avoir à vous soucier du "suis-je vraiment, totalement, 100% certain qui ==se comportera comme je le pense?"
STW
7
@STW - un exemple pour lequel Crockford n'est pas l'alpha et l'oméga de JavaScript, est son conseil de ne pas utiliser l'incrémentation / décrémentation unaire ( ++/ --).
Marcel Korpel
10
Et n'utilisez jamais ++ou --ou des if/elsedéclarations sur une seule ligne ou continueou l' newopérateur ou tout autre nombre de pratiques de code parfaitement légitimes que Crockford a jugées "nuisibles". Et bien sûr, ne pensez jamais à penser à utiliser evalou withmême si leurs pièges sont bien compris. Et avez-vous vu la prochaine version de JS? Une syntaxe plus stricte et une poignée de fonctions d'aide, dont certaines flottent depuis des années, sont à peu près tout ce que nous obtenons après tout ce temps. La syntaxe n'a pas du tout évolué. Si Crockford est derrière tout ça, alors c'est une mauvaise chose.
MooGoo
4
@CoffeeAddict - un test rapide dans JSFiddle semble en désaccord. Ils sont tous deux sensibles à la casse: jsfiddle.net/st2EU
STW
205

Si vous savez qu'il s'agit de chaînes, il n'est pas nécessaire de vérifier le type.

"a" == "b"

Cependant, notez que les objets chaîne ne seront pas égaux.

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

retournera faux.

Appelez la méthode valueOf () pour la convertir en primitive pour les objets String,

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

reviendra vrai

Anurag
la source
4
merci pour ce JSS, deux objets chaîne ne seront jamais égaux sauf s'ils sont le même objet quelle que soit la valeur.
Anurag
4
@JSS: En outre, new String("a") == "a"est vrai (mais ne le serait pas ===), car le côté gauche sera converti en une valeur de chaîne primitive.
Matthew Crumley
5
@JSS: new String("a") == new String("a"), new String("a") === new String("b"), new String("a") === new String("a")retournerez tous false, puisque vous traitez avec des références à des objets de la Stringclasse, et non pas des primitives de type string.
palswim
4
Juste pour clarifier cela pour quiconque le lit. new String(foo)crée un objet chaîne et String(foo) convertit foo en une primitive chaîne.
Brigand
9
@FakeRainBrigand - clair comme de la boue, mais c'est à cela que servent les javascripts, n'est-ce pas?
Periata Breatta
59

Un seul ajout aux réponses: si toutes ces méthodes retournent false, même si les chaînes semblent être égales, il est possible qu'il y ait un espace à gauche et à droite d'une chaîne. Donc, mettez juste un .trim()à la fin des chaînes avant de comparer:

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

J'ai perdu des heures à essayer de comprendre ce qui ne va pas. J'espère que cela aidera quelqu'un!

akelec
la source
1
Merci beaucoup. C'est étrange pour moi cependant, car je me suis assuré qu'il n'y avait pas d'espace à gauche ou à droite et c'était toujours le seul moyen de résoudre mon problème. Peut-être est-ce lié à la représentation interne d'une chaîne?
Niko
2
Merci @akelec !! @Niko, c'était probablement dû au caractère Zero-Width-Space qui est invisible à l'œil nu. Voir en.wikipedia.org/wiki/Zero-width_space . Même si ce personnage a ses objectifs, de nombreux développeurs en veulent à son existence!
stwr667
Merci, c'était frustrant car la vérification de l'égalité dans mon if échouait, mais je n'ai vu aucun espace lors de l'inspection lors du débogage.
drzounds
Un problème courant lors du chargement d'une variable à partir d'un fichier texte (ie: utilisation fetch). Merci beaucoup.
Sopalajo de Arrierez
@SopalajodeArrierez, exactement, il y a surtout un espace ou un retour chariot à la fin de la chaîne. Je vous en prie.
akelec
22

ce qui m'a amené à cette question est le paddingetwhite-spaces

vérifier mon cas

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

et le titre était " LastName"

entrez la description de l'image ici

alors peut-être que vous devez utiliser une trimfonction comme celle-ci

var title = $(this).text().trim();
Basheer AL-MOMANI
la source
2
Merci même ici, j'ai utilisé .toString().trim()dans
Typescript
17

À moins que vous ne sachiez vraiment comment fonctionne la coercition, vous devez éviter ==et utiliser l'opérateur d'identité à la ===place. Mais vous devriez lire ceci pour comprendre comment cela fonctionne .

Si vous utilisez ==, vous laissez la langue exercer une certaine contrainte de type pour vous, par exemple:

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

Comme l'a dit Douglas Crockford dans son livre:

Il vaut toujours mieux utiliser l'opérateur d'identité.

ludico8
la source
3
Bien que ce lien puisse répondre à la question, il est préférable d'inclure les parties essentielles de la réponse ici et de fournir le lien de référence. Les réponses de lien uniquement peuvent devenir invalides si la page liée change.
Parkash Kumar du
{}==" "m'a donné Unexpected token ==quelle est la bonne façon de le faire?
Basheer AL-MOMANI
12

Il existe en fait deux façons de créer des chaînes en javascript.

  1. var str = 'Javascript'; Cela crée une valeur de chaîne primitive.

  2. var obj = new String('Javascript');Cela crée un objet wrapper de type String.

    typeof str // string
    typeof obj // object

Ainsi, la meilleure façon de vérifier l'égalité est d'utiliser l' ===opérateur car il vérifie la valeur ainsi que le type des deux opérandes.

Si vous souhaitez vérifier l'égalité entre deux objets, l'utilisation String.prototype.valueOfest la bonne façon.

new String('javascript').valueOf() == new String('javascript').valueOf()
Abhishek
la source
6

La chaîne Objectspeut être vérifiée à l'aide d'une JSON.stringyfy()astuce.

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

Muhammad Usman
la source
1

Étant donné que les deux chaînes peuvent être très grandes, il existe deux approches principales bitwise searchetlocaleCompare

Je recommande cette fonction

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

La façon la plus simple de le faire est d'utiliser un opérateur ternaire comme ceci:

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

mais si la chaîne que vous souhaitez comparer est dans un tableau, vous utiliserez le filtre es6

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

ce qui précède vérifiera votre stringArray et toute chaîne qui lui correspond dans le tableau qui dans notre cas, nous avons choisi "boys"

Pedro JR
la source
-8

J'ai trouvé une solution alternative lors des tests. vous pouvez utiliser la fonction sur le prototype de chaîne.

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

fonctionne bien dans les navigateurs chromés

Khorram Bin Salim Khondkar
la source
La question demande comment vérifier si "hello world" = "hello world", pas comment vérifier si "hello world" est une chaîne.
Nick
4
C'est idiot. Vous avez créé une version Rube Goldberg de ==.
JJJ
Salut OP, votre montage est complètement différent dans sa partie spirituelle, et votre réponse a déjà trop de votes négatifs. Je vous prie instamment de supprimer cette réponse et d'en poster une nouvelle avec votre version modifiée
Yılmaz Durmaz