L'operateur === en JavaScript (Strict equality Operator)
En lisant les sources de Microsoft Ajax Library (Beta 1) j'ai constaté l'utilisation (massive) de l'opérateur "===" (strict equality operator). Curieux j'ai cherché ce que cela voulait dire exactement, j'ai donc directement regardé les specs de JavaScript aussi connu sous le nom de ECMA-262 Edition 3.
Voici la doc officielle :
11.9.6 The Strict Equality Comparison Algorithm
The comparison x === y, where x and y are values, produces true or false. Such a comparison is performed as
follows:
- If Type(x) is different from Type(y), return false.
- If Type(x) is Undefined, return true.
- If Type(x) is Null, return true.
- If Type(x) is not Number, go to step 11.
- If x is NaN, return false.
- If y is NaN, return false.
- If x is the same number value as y, return true.
- If x is +0 and y is -0, return true.
- If x is -0 and y is +0, return true.
- Return false.
- If Type(x) is String, then return true if x and y are exactly the same sequence of characters (same length and same characters in corresponding positions); otherwise, return false.
- If Type(x) is Boolean, return true if x and y are both true or both false; otherwise, return false.
- Return true if x and y refer to the same object or if they refer to objects joined to each other (section 13.1.2). Otherwise, return false.
Pour une fois on ne peut pas dire que les spécification ne sont pas simple, mais quelle est la différence avec l'opérateur == ?
11.9.3 The Abstract Equality Comparison Algorithm
The comparison x == y, where x and y are values, produces true or false. Such a comparison is performed as follows:
- If Type(x) is different from Type(y), go to step 14.
- If Type(x) is Undefined, return true.
- If Type(x) is Null, return true.
- If Type(x) is not Number, go to step 11.
- If x is NaN, return false.
- If y is NaN, return false.
- If x is the same number value as y, return true.
- If x is +0 and y is -0, return true.
- If x is -0 and y is +0, return true.
- Return false.
- If Type(x) is String, then return true if x and y are exactly the same sequence of characters (same length and same characters in corresponding positions). Otherwise, return false.
- If Type(x) is Boolean, return true if x and y are both true or both false. Otherwise, return false.
- Return true if x and y refer to the same object or if they refer to objects joined to each other (section 13.1.2).Otherwise, return false.
- If x is null and y is undefined, return true.
- If x is undefined and y is null, return true.
- If Type(x) is Number and Type(y) is String,return the result of the comparison x == ToNumber(y).
- If Type(x) is String and Type(y) is Number,return the result of the comparison ToNumber(x) == y.
- If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.
- If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
- If Type(x) is either String or Number and Type(y) is Object,return the result of the comparison x == ToPrimitive(y).
- If Type(x) is Object and Type(y) is either String or Number,return the result of the comparison ToPrimitive(x) == y.
- Return false
La première grosse différence se situe au niveau de l'inteprétation des arguments. prenons des exemples.
var a1 = ('1' == 1); // true
var a2 = ('1' === 1); // false
var a3 = ('true' == true); // true
var a4 = ('true' === true); // false
Voici un autre cas un peu plus interessant qui nous permet de comparer des objets complexe avec un literal.
var Personne = function(firstName, lastName){
this._firstName = firstName;
this._lastName = lastName;
}
Personne.prototype.toString = function(){
return this._firstName + ' ' + this._lastName;
}
var p = new Personne('Cyril', 'DURAND');
var b1 = (p == 'Cyril DURAND'); // true
var b1 = (p === 'Cyril DURAND'); // false
D'autres petits exemples où l'opérateur "==" se comporte de la même façon que l'opérateur "==="
var p1 = new Personne('Cyril', 'DURAND');
var p2 = new Personne('Cyril', 'DURAND');
var c1 = (p1 == p2); // false
var c2 = (p1 === p2); // false
var p1 = new Personne('Cyril', 'DURAND');
var p2 = p1;
var c1 = (p1 == p2); // true
var c2 = (p1 === p2); // true
En appelant une fonction avec un paramètre non renseigné, l'opérateur "===" nous permet de savoir si l'argument vaut null où a été omis.
function toto(val){
var d1 = (val == null); // true
var d2 = (val === null); // false
}
toto()
Conclusion
La différence entre "==" et "===" et que l'opérateur "==" vérifie seulement la valeur alors que l'opérateur "===" vérfie en plus le type.
Cela peut être interessant pour connaitre les arguments optionels des fonctions mais je ne comprend pas quel est l'intérêt de l'utiliser aussi massivement, cela gaspille un caractère "inutilement" ! J'opte pour les performances puisque l'opérateur "===" n'évalue pas les arguments, mais les quelques tests que j'ai effectués m'indique le contraire. En plus il est trés difficile de trouver de la doc sur les opérateurs puisqu'il sont composé de caracteres spéciaux. Si quelqu'un a des infos la dessus, je suis preneur.
Je viens de me rappeller un billet de Bertrand Leroy : I love Javascript! en gros son explication et que puisque "===" vérifie aussi le type alors c'est mieux que "==" et la seule raison de ne pas l'utiliser c'est pour gagner un caractère ... ce qui représente "quand même" 109 octets dans le fichier MicrosoftAjax.js. Je vais me satisfaire de cette réponse, même si j'aimerais bien avoir confirmation que "==" n'est pas plus rapide que "===".