5651 votes

Quel opérateur d'égalité (== ou ===) doit être utilisé dans les comparaisons JavaScript ?

J'utilise JSLint pour passer par JavaScript, et il renvoie de nombreuses suggestions pour remplacer == (deux signes égaux) avec === (trois signes égaux) pour des opérations telles que la comparaison entre idSele_UNVEHtype.value.length == 0 à l'intérieur d'un if déclaration.

Y a-t-il un avantage en termes de performance à remplacer == avec === ?

Toute amélioration des performances serait la bienvenue car il existe de nombreux opérateurs de comparaison.

Si aucune conversion de type n'a lieu, y aurait-il un gain de performance par rapport à l'option == ?

7049voto

Bill the Lizard Points 147311

L'opérateur d'égalité stricte ( === ) se comporte de manière identique à l'opérateur d'égalité abstrait ( == ) sauf qu'aucune conversion de type n'est effectuée et que les types doivent être les mêmes pour être considérés comme égaux.

Référence : Tutoriel Javascript : Opérateurs de comparaison

Le site == l'opérateur comparera pour l'égalité après avoir effectué toutes les conversions de type nécessaires . Le site === l'opérateur pas effectue la conversion, donc si deux valeurs ne sont pas du même type === retournera simplement false . Les deux sont aussi rapides l'un que l'autre.

Pour citer l'excellent ouvrage de Douglas Crockford JavaScript : Les bons côtés ,

JavaScript possède deux ensembles d'opérateurs d'égalité : === et !== et leurs jumeaux maléfiques == et != . Les bons fonctionnent de la façon dont on s'y attend. Si les deux opérandes sont du même type et ont la même valeur, alors === produit true et !== produit false . Les jumeaux maléfiques font la bonne chose lorsque les opérandes sont du même type, mais s'ils sont de types différents, ils tentent de contraindre les valeurs. Les règles par lesquelles ils le font sont compliquées et peu mémorisables. Voici quelques-uns des cas intéressants :

'' == '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

Equality Comparison Table

Le manque de transitivité est alarmant. Mon conseil est de ne jamais utiliser les jumeaux maléfiques. A la place, utilisez toujours === et !== . Toutes les comparaisons qui viennent d'être présentées produisent false avec le === opérateur.


Mise à jour :

Un bon point a été soulevé par @Casebash dans les commentaires et dans @Phillipe Laybaert's réponse concernant les objets. Pour les objets, == et === agissent de manière cohérente les uns avec les autres (sauf dans un cas particulier).

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

Le cas particulier est celui de la comparaison d'une primitive avec un objet qui évalue la même primitive, en raison de son statut de primitif. toString ou valueOf méthode. Par exemple, considérons la comparaison d'une chaîne de caractères primitive avec un objet chaîne de caractères créé à l'aide de la méthode String constructeur.

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

Ici, le == vérifie les valeurs des deux objets et renvoie l'opérateur true mais le === c'est de voir qu'ils ne sont pas du même type et de retourner false . Laquelle est la bonne ? Cela dépend vraiment de ce que vous essayez de comparer. Mon conseil est de contourner entièrement la question et de ne pas utiliser l'option String pour créer des objets chaîne de caractères à partir de chaînes de caractères.

Référence
http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3

9 votes

J'aimerais également souligner que 0 === -0 et NaN !== NaN, ce qui peut parfois prêter à confusion. Si vous voulez différencier ±0 et considérer les NaN comme égaux, utilisez Object.is (ES2015)

8 votes

La frappe douce est une fonctionnalité . Il est évident que Crockford met en évidence certains des "artefacts" de cette décision de conception, mais la saisie souple reste une fonctionnalité. Si elle est utilisée correctement, c'est très bien à utiliser. Ne jetez pas le bébé avec l'eau du bain.

0 votes

Pourquoi auriez-vous besoin d'utiliser -0 ?

1233voto

Andreas Grech Points 39188

Utilisation de la == opérateur ( Égalité )

true == 1; //true, because 'true' is converted to 1 and then compared
"2" == 2;  //true, because "2" is converted to 2 and then compared

Utilisation de la === opérateur ( Identité )

true === 1; //false
"2" === 2;  //false

Cela s'explique par le fait que le opérateur d'égalité == fait de la coercition de type ce qui signifie que l'interprète essaie implicitement de convertir les valeurs avant de les comparer.

D'autre part, le opérateur identitaire === ne fait pas de coercition de type et ne convertit donc pas les valeurs lors de la comparaison, ce qui la rend plus rapide (comme le prévoit l'article 3.1.1 de la loi sur la protection de l'environnement). Cette référence JS ) car il saute une étape.

1 votes

Je ne pense pas que l'identité est le terme correct ici/ === vérifie l'égalité et le type (appelé stricte ). Idendité se réfère généralement à la "similitude", qui est assurée par le système de gestion de l'information de l'UE. Object.is (conformément à la norme ES2015).

865voto

SNag Points 1342

Une représentation graphique intéressante de la comparaison d'égalité entre == et === .

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


var1 === var2

Lorsque vous utilisez === pour le test d'égalité JavaScript, tout est tel quel. Rien n'est converti avant d'être évalué.

Equality evaluation of === in JS


var1 == var2

Lorsque vous utilisez == pour le test d'égalité JavaScript, certaines conversions funky ont lieu.

Equality evaluation of == in JS


Conclusion :

Utilisez toujours === .

(A moins que vous ne compreniez parfaitement les conversions qui ont lieu avec == .)

7 votes

Une meilleure table "==" : algassert.com/visualisation/2014/03/27/

0 votes

Au moins == les comparaisons sont commutatives (c'est-à-dire (a==b) === (b==a)) XD

0 votes

@imkzh Les relations sont plus communément appelées symétrique plutôt que commutatif . Mais ce que je suis venu dire ici, c'est que == n'est pas transitif ! (même en ignorant NaN )

650voto

Philippe Leybaert Points 62715

Dans les réponses ici, je n'ai rien lu sur ce que égal moyens. Certains diront que === signifie égaux et de même type mais ce n'est pas vraiment vrai. Cela signifie en fait que les deux opérandes font référence au même objet ou en cas de ont la même valeur .

Prenons le code suivant :

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

La même chose ici :

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

Ou même :

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

Ce comportement n'est pas toujours évident. Il n'y a pas que l'égalité et le fait d'être du même type.

La règle est la suivante :

Pour les types de valeurs (nombres) :
a === b retourne vrai si a et b ont la même valeur et sont du même type

Pour les types de référence :
a === b retourne vrai si a et b font référence à l'exact même objet

Pour les cordes :
a === b retourne vrai si a et b sont toutes deux des chaînes de caractères et contiennent exactement les mêmes caractères


Cordes : le cas particulier...

Les chaînes de caractères ne sont pas des types de valeurs, mais en Javascript elles se comportent comme des types de valeurs, donc elles seront "égales" lorsque les caractères de la chaîne sont les mêmes et lorsqu'elles sont de la même longueur (comme expliqué dans la troisième règle).

Maintenant, ça devient intéressant :

var a = "12" + "3";
var b = "123";

alert(a === b); // returns true, because strings behave like value types

Mais que pensez-vous de ça ?

var a = new String("123");
var b = "123";

alert(a === b); // returns false !! (but they are equal and of the same type)

Je pensais que les chaînes de caractères se comportaient comme des types de valeurs ? Eh bien, cela dépend à qui vous demandez... Dans ce cas, a et b ne sont pas le même type. a est de type Object alors que b est de type string . Rappelez-vous que la création d'un objet chaîne à l'aide de la fonction String Le constructeur crée un objet de type Object qui se comporte comme une chaîne la plupart du temps .

282voto

nalply Points 4675

Permettez-moi d'ajouter ce conseil :

En cas de doute, lisez le spécification !

L'ECMA-262 est la spécification d'un langage de script dont JavaScript est un dialecte. Bien sûr, dans la pratique, le comportement des principaux navigateurs importe davantage qu'une définition ésotérique de la manière dont quelque chose est censé être traité. Mais il est utile de comprendre pourquoi new String("a") !== "a" .

Laissez-moi vous expliquer comment lire le cahier des charges pour clarifier cette question. Je vois que dans ce très vieux sujet, personne n'a eu de réponse pour cet effet très étrange. Donc, si vous pouvez lire une spécification, cela vous aidera énormément dans votre profession. C'est une compétence acquise. Alors, continuons.

La recherche de === dans le fichier PDF m'amène à la page 56 de la spécification : 11.9.4. L'opérateur d'égalité stricte ( === ) et, après avoir parcouru le jargon spécifique, j'ai trouvé :

11.9.6 L'algorithme de comparaison d'égalité stricte
La comparaison x === y, où x et y sont des valeurs, produit vrai ou faux . Une telle comparaison est effectuée comme suit :
  1. Si Type(x) est différent de Type(y), retourner faux .
  2. Si Type(x) est indéfini, retourner vrai .
  3. Si Type(x) est Null, retourner vrai .
  4. Si Type(x) n'est pas Nombre, passez à l'étape 11.
  5. Si x est NaN , retour faux .
  6. Si y est NaN , retour faux .
  7. Si x a la même valeur numérique que y, retourner vrai .
  8. Si x est +0 et y est 0, retourner vrai .
  9. Si x est égal à 0 et y est égal à +0, retourner vrai .
  10. Retour faux .
  11. Si Type(x) est String, alors on retourne vrai si x et y sont exactement la même séquence de caractères (même longueur et mêmes caractères dans les positions correspondantes) ; sinon, retourner faux .
  12. Si Type(x) est booléen, retourner vrai si x et y sont tous deux vrai ou les deux faux ; sinon, retour faux .
  13. Retour vrai si x et y font référence au même objet ou s'ils font référence à des objets joints l'un à l'autre (voir 13.1.2). Sinon, on retourne faux .

L'étape 11 est intéressante. Oui, les chaînes de caractères sont traitées comme des types de valeurs. Mais cela n'explique pas pourquoi new String("a") !== "a" . Avons-nous un navigateur non conforme à la norme ECMA-262 ?

Pas si vite !

Vérifions les types des opérandes. Essayez de le faire vous-même en les entourant de typeof() . Je trouve que nouveau String("a") est un objet, et l'étape 1 est utilisée : return faux si les types sont différents.

Si vous vous demandez pourquoi nouveau String("a") ne renvoie pas une chaîne de caractères, que diriez-vous d'un exercice de lecture d'une spécification ? Amusez-vous bien !


Aidiakapi a écrit ceci dans un commentaire ci-dessous :

Extrait du cahier des charges

11.2.2 Le nouvel opérateur :

Si le Type(constructeur) n'est pas Object, on lève une exception TypeError.

En d'autres termes, si String ne serait pas de type Object, il ne pourrait pas être utilisé avec l'opérateur new.

nouveau renvoie toujours un objet, même pour Chaîne de caractères constructeurs, aussi. Et hélas ! La sémantique des valeurs pour les chaînes de caractères (voir étape 11) est perdue.

Et cela signifie finalement : new String("a") !== "a" .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X