Подтвердить что ты не робот

'\n\t\r' == 0 верно?

Сегодня, когда я экспериментировал с ==, я случайно узнал, что "\n\t\r" == 0. Как на самом деле "\n\t\r" равно 0 или false?

Что я сделал:

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

И это действительно раздражает меня. Поэтому я сделал больше:

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

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

Это не имеет никакого смысла. Как это происходит? И еще более сумасшедший:

//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.");
}

Что это дает мне: Variable is not declared.

Как он равен 0 или false

4b9b3361

Ответ 1

Такое поведение может быть неожиданным, но его можно объяснить, посмотрев спецификацию.

Мы должны посмотреть на то, что происходит, когда выполняется сравнение с equals operator. Точный алгоритм определен в разделе 11.9.3.


string == integer

Шаг, на который мы должны обратить внимание: # 5:

5. Если Type(x) - String, а Type(y) - Number,
верните результат сравнения ToNumber(x) == y.

Это означает, что строка "\n" ("\r", "\t") сначала преобразуется в число, а затем сравнивается с 0.

Как строка преобразуется в число? Это объясняется в разделе раздел 9.3.1. Короче говоря, мы имеем:

Значение MV (математическое значение) StringNumericLiteral ::: StrWhiteSpace равно 0.

где StrWhiteSpace определяется как

StrWhiteSpace :::
    StrWhiteSpaceChar StrWhiteSpace_opt

StrWhiteSpaceChar :::
    WhiteSpace
    LineTerminator

Это означает, что числовое значение строк, содержащих пробелы, и/или терминатор линии 0.
Какие символы считаются символами пробела, определены в разделе раздел 7.3.


string == boolean

Шаг, на который мы должны обратить внимание: # 7:

7. Если тип (y) булев, верните результат сравнения x == ToNumber(y).

Как логические переменные преобразуются в числа, довольно просто: true становится 1 и false становится 0.

Затем мы сравниваем строку с числом, которое описано выше.


Как отмечали другие, для избежания этой "проблемы" можно использовать строгое сравнение (===). На самом деле вам следует использовать только обычное сравнение, если вы знаете, что делаете, и хотите, чтобы это поведение.

Ответ 2

Поскольку JavaScript является свободно типизированным языком, он пытается набирать вашу первую сторону сравнения в другую, чтобы они соответствовали друг другу.

Любая строка, которая не содержит числа, становится 0 по сравнению с целым числом и становится истинным (за исключением определенных ситуаций) по сравнению с логическим.

Световые материалы для чтения.

Ответ 3

txt не является Boolean, поэтому он никогда не будет false. Это может быть undefined.

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

Кстати, объявленная переменная может быть undefined (например, var txt;).

Если вы выполняете более строгое сравнение (без принуждения типа, используя ===), вы увидите, что

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

См. также

Ответ 4

Причина в том, что "\n\t\r" так же, как " " рассматриваются как пустые строки. Если вы используете ==, он вернет true, но если вы используете ===, он вернет false.

Если вы хотите проверить существование, вы должны использовать что-то вроде

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

Ответ 5

Всякий раз, когда вы используете == operator и пытаетесь сравнить строку с числом, строка сначала будет преобразована в число. Таким образом: alert("\n\r"==0) becomes: alert(Number("\n\r")==0) Конструкция числа является интересной. Сначала будет разбит пробел, а затем определит, не является ли число числом или нет. Если NaN, то результатом будет "NaN". Если строка пуста, то результат равен 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

Чтобы проверить, является ли результат использованием NaN isNaN()

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

однако заметьте, что NaN никогда не будет равно NaN:

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

Update:

если вы хотите проверить, являются ли обе стороны NaN, вы сначала конвертируете оба значения в логические значения следующим образом:

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

или еще лучше

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