Question Quel opérateur égal (== vs ===) devrait être utilisé dans les comparaisons JavaScript?


j'utilise JSLint passer par JavaScript, et il retourne de nombreuses suggestions pour remplacer == (deux signes égaux) avec === (trois signes égaux) en faisant des choses comme la comparaison idSele_UNVEHtype.value.length == 0 à l'intérieur d'un if déclaration.

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

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

Si aucune conversion de type n'a lieu, y aurait-il un gain de performance ==?


5674
2017-12-11 14:19


origine


Réponses:


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

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

le == l'opérateur va comparer pour l'égalité après avoir effectué toutes les conversions de type nécessaires. le === l'opérateur ne pas faire la conversion, donc si deux valeurs ne sont pas du même type === reviendra simplement false. Les deux sont également rapides.

Pour citer l'excellent Douglas Crockford JavaScript: Les bonnes parties,

JavaScript a deux ensembles d'opérateurs d'égalité: === et !==et leurs jumeaux maléfiques == et !=. Les bons fonctionnent comme vous le souhaitez. Si les deux opérandes sont du même type et ont la même valeur, alors === produit true et !== produit false. Les jumeaux pervers font la bonne chose quand 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 font cela sont compliquées et immémoriales. Ce sont 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

Le manque de transitivité est alarmant. Mon conseil est de ne jamais utiliser les jumeaux maléfiques. Au lieu de cela, utilisez toujours === et !==. Toutes les comparaisons juste montrées produisent false avec le === opérateur.


Mettre à jour:

Un bon point a été soulevé par @Casebash dans les commentaires et dans @Phillipe Laybaert  répondre concernant les types de référence. Pour les types de référence == et === agir 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 lorsque vous comparez un littéral avec un objet qui évalue le même littéral, en raison de son toString ou valueOf méthode. Par exemple, considérons la comparaison d'un littéral de chaîne avec un objet de chaîne créé par le String constructeur.

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

Ici le == l'opérateur vérifie les valeurs des deux objets et retourne true, mais le === est de voir qu'ils ne sont pas du même type et de retour false. Laquelle est correcte? Cela dépend vraiment de ce que vous essayez de comparer. Mon conseil est de contourner complètement la question et de ne pas utiliser le String constructeur pour créer des objets chaîne.

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


5716
2017-12-11 14:25



En utilisant le ==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

En utilisant le ===opérateur (Identité)

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

C'est parce que le Opérateur égalité == fait taper la coercition, ce qui signifie que l'interpréteur essaie implicitement de convertir les valeurs avant de les comparer.

D'un autre côté, le opérateur d'identité === ne fait pas de coercition de type, et ne convertit donc pas les valeurs lors de la comparaison.


988
2018-06-05 19:11



Dans les réponses ici, je n'ai rien lu sur ce que égal veux dire. Certains diront que === veux dire égal et du même type, mais ce n'est pas vraiment vrai. Cela signifie en fait que les deux opérandes référencent le même objetou en cas de types de valeur, ont la même valeur.

Alors, 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

Pareil 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 y a plus dans l'histoire que d'être égal et d'être du même type.

La règle est:

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

Pour les types de référence:
a === b renvoie vrai si a et b référence le même objet exact

Pour les chaînes:
a === b renvoie vrai si a et b sont à la fois les chaînes et contiennent exactement les mêmes caractères


Cordes: le cas particulier ...

Les chaînes ne sont pas des types de valeur, mais en Javascript, elles se comportent comme des types de valeur, donc elles seront "égales" quand les caractères de la chaîne sont identiques et quand ils ont 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 qu'en est-il de cela?

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 se comportent comme des types de valeur? Eh bien, cela dépend de qui vous demandez ... Dans ce cas, a et b ne sont pas du même type. a est de type Object, tandis que b est de type string. Rappelez-vous juste que créer un objet chaîne en utilisant le String constructeur crée quelque chose de type Object qui se comporte comme une chaîne la plupart du temps.


545
2018-05-05 05:21



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

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


var1 === var2

En utilisant === Pour tester l'égalité JavaScript, tout est tel quel. Rien n'est converti avant d'être évalué.

Equality evaluation of === in JS


var1 == var2

En utilisant == pour les tests d'égalité JavaScript, certains   les conversions géniales ont lieu.

Equality evaluation of == in JS

Morale de l'histoire: 

Utilisation === sauf si vous comprenez parfaitement   les conversions qui ont lieu avec ==.


519
2017-11-28 18:18



Laissez-moi ajouter ce conseil:

En cas de doute, lisez le spécification! 

ECMA-262 est la spécification pour un langage de script dont JavaScript est un dialecte. Bien sûr, dans la pratique, il importe plus de savoir comment les navigateurs les plus importants se comportent qu'une définition ésotérique de la façon dont quelque chose est censé être géré. Mais il est utile de comprendre pourquoi new String ("a")! == "a".

S'il vous plaît laissez-moi vous expliquer comment lire la spécification pour clarifier cette question. Je vois que dans ce très vieux sujet, personne n'a eu de réponse pour l'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 du fichier PDF pour === m'amène à la page 56 du cahier des charges: 11.9.4. L'opérateur strict égal (===), et après avoir pataugé à travers les spécifications, je trouve:

11.9.6 L'algorithme de comparaison de l'é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 du Type (y), retour faux.
  2. Si le type (x) est indéfini, renvoyer vrai.
  3. Si Type (x) est Null, retour vrai.
  4. Si Type (x) n'est pas Numéro, passez à l'étape 11.
  5. Si x est NaN, revenir faux.
  6. Si y est NaN, revenir faux.
  7. Si x est la même valeur que y, renvoyer vrai.
  8. Si x est +0 et y est -0, retour vrai.
  9. Si x est -0 et y est +0, retour vrai.
  10. Retour faux.
  11. Si Type (x) est String, retour 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, retour faux.
  12. Si le type (x) est booléen, renvoyer vrai si x et y sont tous les deux vrai ou les deux faux; sinon, retour faux.
  13. Retour vrai si x et y se réfèrent au même objet ou s'ils se rapportent à des objets joints les uns aux autres (voir 13.1.2). Sinon, retour faux.

Intéressant est l'étape 11. Oui, les chaînes sont traitées comme des types de valeur. Mais cela n'explique pas pourquoi new String ("a")! == "a". Avons-nous un navigateur non conforme à ECMA-262?

Pas si vite!

Vérifions les types des opérandes. Essayez-le par vous-même en les enveloppant Type de(). Je trouve que nouvelle chaîne ("a") est un objet, et l'étape 1 est utilisée: retour faux si les types sont différents.

Si vous vous demandez pourquoi nouvelle chaîne ("a") ne renvoie pas une chaîne, que diriez-vous d'un exercice de lecture d'une spécification? S'amuser!


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

De la spécification

11.2.2 Le nouvel opérateur:

Si Type (constructeur) n'est pas Object, lance une exception TypeError.

Avec d'autres mots, si String ne serait pas de type Object, il ne pourrait pas être utilisé avec le nouvel opérateur.

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

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


250
2018-05-12 12:58



En PHP et JavaScript, c'est un opérateur d'égalité strict. Ce qui signifie, il va comparer à la fois le type et les valeurs.


93
2017-12-25 11:17



J'ai testé cela dans Firefox avec Pyromane en utilisant un code comme celui-ci:

console.time("testEquality");
var n = 0;
while(true) {
    n++;
    if(n==100000) 
        break;
}
console.timeEnd("testEquality");

et

console.time("testTypeEquality");
var n = 0;
while(true) {
    n++;
    if(n===100000) 
        break;
}
console.timeEnd("testTypeEquality");

Mes résultats (testés cinq fois chacun et moyennés):

==: 115.2
===: 114.4

Donc je dirais que la différence minuscule (c'est plus de 100000 itérations, souvenez-vous) est négligeable. Performance n'est pas une raison de faire ===. Tapez sécurité (bien, aussi sûr que vous allez obtenir en JavaScript), et la qualité du code est.


88
2018-05-12 12:58



En JavaScript, cela signifie de la même valeur et du même type.

Par exemple,

4 == "4" // will return true

mais

4 === "4" // will return false 

84
2017-12-11 14:58



le === opérateur est appelé un opérateur de comparaison stricte, il Est-ce que différer de la == opérateur.

Prenons 2 vars a et b.

Pour "a == b" évaluer à vrai a et b doivent être le même valeur.

Dans le cas de "a === b" a et b doivent être les même valeur et aussi du même type pour qu'il évalue à vrai.

Prenons l'exemple suivant

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 résumé; en utilisant le == l'opérateur peut évaluer à vrai dans les situations où vous ne le souhaitez pas en utilisant le === l'opérateur serait plus sûr.

Dans le scénario d'utilisation à 90%, peu importe celui que vous utilisez, mais il est pratique de connaître la différence lorsque vous obtenez un comportement inattendu un jour.


72
2018-05-12 12:58