J'utilise [JSLint][1] pour parcourir JavaScript, et il me renvoie de nombreuses suggestions pour remplacer les ==
(deux signes égaux) par des ===
(trois signes égaux) lorsque je fais des choses comme comparer idSele_UNVEHtype.value.length == 0
dans une instruction if
.
Le remplacement de ==
par ===
présente-t-il un avantage en termes de performances ?
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'opérateur d'identité (===
) se comporte de la même manière que l'opérateur d'égalité (==
), 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][1]
L'opérateur ==
compare l'égalité après avoir effectué les conversions de type nécessaires. L'opérateur ===
ne fera pas 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 : The Good Parts][2],
JavaScript possède deux ensembles d'opérateurs d'égalité :
===
et!==
, et leurs jumeaux maléfiques==
et!=
. Les bons opérateurs fonctionnent comme on s'y attend. Si les deux opérandes sont du même type et ont la même valeur, alors===
produitvrai
et!==
produitfaux
. 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 impossibles à mémoriser. Voici quelques-uns des cas intéressants :
'' == '0' // faux 0 == '' // true 0 == '0' // true
false == 'false' // false false == '0' // true
false == undefined // false false == null // false null == undefined // true
' \t\r\n ' == 0 // vrai
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 que nous venons de montrer produisentfalse
avec l'opérateur===
.
Un bon point a été soulevé par [@Casebash][3] dans les commentaires et dans [@Phillipe Laybaert][4] la réponse concernant les types de référence. Pour les types de référence, ==
et ===
agissent de manière cohérente l'un avec l'autre (sauf dans un cas spécial).
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 où vous comparez un littéral avec un objet qui évalue le même littéral, grâce à sa méthode toString
ou valueOf
. Par exemple, considérons la comparaison d'un littéral de chaîne de caractères avec un objet chaîne de caractères créé par le constructeur String
.
"abc" == new String("abc") // true
"abc" === new String("abc") // false
Dans ce cas, l'opérateur ==
vérifie les valeurs des deux objets et renvoie "vrai", mais l'opérateur ===
voit qu'ils ne sont pas du même type et renvoie "faux". Lequel des deux est correct ? Cela dépend vraiment de ce que vous essayez de comparer. Mon conseil est de contourner la question et de ne pas utiliser le constructeur String
pour créer des objets de type chaîne.
Référence http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3
[1] : http://www.c-point.com/javascript_tutorial/jsgrpComparison.htm [2] : http://www.amazon.com/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742 [3] : https://stackoverflow.com/users/165495/casebash [4] : https://stackoverflow.com/users/113570/philippe-leybaert
Utilisation de l'opérateur ==
(Equality)
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 l'opérateur ===
(Identité)
true === 1; //false
"2" === 2; //false
Cela est dû au fait que l'opérateur d'égalité ==
effectue une coercition de type**, ce qui signifie que l'interpréteur essaie implicitement de convertir les valeurs avant de les comparer.
D'autre part, l'opérateur identité ===
ne fait pas de coercition de type, et donc ne convertit pas les valeurs lors de la comparaison, et est donc plus rapide (selon le test [This JS benchmark][1]) car il saute une étape.
[1] : http://jsben.ch/JUOm2
Il est peu probable qu'il y ait une différence de performance entre les deux opérations dans votre utilisation. Il n'y a pas de conversion de type à effectuer car les deux paramètres sont déjà du même type. Les deux opérations auront une comparaison de type suivie d'une comparaison de valeur.