'\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
Ответы
Ответ 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));