36 votes

'\n\t\r' == 0 est vraie?

Aujourd'hui, quand je faisais des expériences avec des ==,, j'ai accidentellement découvert qu' "\n\t\r" == 0. Comment sur la terre n' "\n\t\r" égal à 0ou false?

Ce que j'ai fait est:

var txt = "\n";  //new line
txt == 0;        //it gives me true

Et que vraiment m'agacer. Donc je n'ai plus:

var txt = "\r";  //"return"
txt == 0;        //true

var txt = "\t";  //"tab"
txt == 0;        //true

Il ne fait aucun sens du tout. Comment est-ce arrivé? Et le plus fou, c'est ceci:

//Checking for variable declared or not

var txt ="\n\t\r";
if(txt!=false){
    console.log("Variable is declared.");
}else{
    console.log("Variable is not declared.");
}

Ce qu'il me donne est - Variable is not declared.

Comment est-il égal à 0ou false???

42voto

Felix Kling Points 247451

Ce comportement peut être surprenant, mais peut être expliqué par le fait d'avoir un coup d'oeil à la spécification.

On a qu'à regarder ce qui se passe quand une comparaison avec l' égale de l'opérateur est effectuée. L'algorithme exact est défini dans la section 11.9.3.


string == integer

L'étape que nous avons à regarder, c'est #5:

5. Si Type(x) est une Chaîne et d' Type(y) est Nombre,
retourner le résultat de la comparaison, ToNumber(x) == y.

Cela signifie que la chaîne de caractères "\n" ("\r", "\t") est converti en un nombre premier et ensuite comparés 0.

Comment est une chaîne de caractères convertie en un nombre? Ceci est expliqué dans la section 9.3.1. En bref, nous avons:

Le MV (valeur mathématique) de l' StringNumericLiteral ::: StrWhiteSpace est 0.

StrWhiteSpace est défini comme

StrWhiteSpace :::
    StrWhiteSpaceChar StrWhiteSpace_opt

StrWhiteSpaceChar :::
    WhiteSpace
    LineTerminator

Cela signifie que la valeur numérique de chaînes de caractères contenant des caractères espace et/ou un terminateur de ligne est - 0.
Les caractères qui sont considérés comme des caractères espace est défini dans la section 7.3.


string == boolean

L'étape que nous avons à regarder, c'est #7:

7. Si le Type(y) est un Booléen, retourner le résultat de la comparaison, x == ToNumber(y).

Comment les booléens sont converties en nombres est assez simple: true devient 1 et false devient 0.

Après, nous sommes la comparaison d'une chaîne à l'encontre d'un certain nombre, ce qui est expliqué ci-dessus.


Comme d'autres l'ont mentionné, une comparaison stricte (===) peut être utilisé pour éviter ce "problème". En fait, vous ne devriez utiliser la comparaison si vous savez ce que vous faites et que vous voulez ce comportement.

12voto

Second Rikudo Points 59550

Parce que le JavaScript est un langage faiblement typé, il tente de type cast votre 1er côté, de la comparaison à l'autre de sorte qu'elles correspondent les uns aux autres.

Une chaîne qui ne contient pas un nombre, devient 0, comparativement à un entier, et devient vrai (Sauf dans certaines situations), comparativement à une valeur de type Boolean.

Lumière de lecture.

4voto

KooiInc Points 38845

txt n'est pas un Boolean, de sorte qu'il ne sera jamais en false. Il peut être undefined si.

var txt ="\n\t\r";
if(txt !== undefined) { //or just: if (txt)
    console.log("Variable is declared.");
} else {
    console.log("Variable is not declared.");
}
//=> will log: 'Variable is declared.'

Par la façon dont, a déclaré variable peuvent être undefined (par exemple, var txt;).

Si vous n'avez plus strict de la comparaison (sans contrainte de type, à l'aide de ===), vous verrez que

var txt = '\n'; txt === 0; //=> false
var txt = '\r'; txt === 0; //=> false
var txt = '\t'; txt === 0; //=> false

Voir aussi

1voto

Vinothbabu Points 6643

Chaque fois que vous utilisez l' == operator et d'essayer de comparer une chaîne en nombre, la chaîne va d'abord être convertie en nombre. Donc: alert("\n\r"==0) becomes: alert(Number("\n\r")==0) Le Nombre constructure est intéressant. Elle sera la première bande espaces de décider ensuite si le nombre n'est pas un nombre ou pas. Si NaN, alors le résultat est "NaN". Si la chaîne est vide, alors le résultat est 0.

alert(Number()) alerts 0
alert(Number("")) alerts 0
alert(Number(" \n \r \n \t")) alerts 0
alert(Number("blah")) alerts NaN
alert(Number("0xFF")) alerts 255
alert(Number("1E6")) alerts 1000000

Pour vérifier si le résultat est NaN utiliser la fonction isNaN()

Thus: alert(isNaN("blah")) alerts true
Thus: alert(isNaN("")) alerts false
Thus: alert(isNaN("\n")) alerts false
Thus: alert(isNaN(" ")) alerts false

cependant, ne remarque que NaN ne pourra jamais égaler NaN:

var nan=Number("geh");alert(nan==nan);  alerts false 

Mise à jour:

si vous voulez vérifier si les deux côtés sont NaN, alors vous feriez convertir à la fois à des valeurs booléennes premier de la sorte:

var nan=Number("geh");alert(!!nan==!!nan); alerts true

ou mieux encore

var nan=Number("geh");
alert(isNaN(nan)&& isNaN(nan));

1voto

Jeremie Parker Points 2024

La raison en est qu' "\n\t\r" comme " " sont traités comme des chaînes vides. Si vous utilisez == il sera de retour true mais si vous utilisez === il sera de retour false.

Si vous voulez tester l'existence vous devez utiliser quelque chose comme

if(typeof strName !== 'undefined') {
    /*do something with strName*/
} else {
    /*do something without it*/
}

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