在JavaScript中,为什么要isNaN(" ")
评估为false
,但要isNaN(" x")
评估为true
?
我在一个文本输入字段进行数字运算,和我正在检查该字段为null
,""
或NaN
。当有人在该字段中输入少量空格时,我的所有三个验证都失败了,我困惑为什么它无法通过isNaN
检查。
"" == false // true
和isNaN(" ") // false
在JavaScript中,为什么要isNaN(" ")
评估为false
,但要isNaN(" x")
评估为true
?
我在一个文本输入字段进行数字运算,和我正在检查该字段为null
,""
或NaN
。当有人在该字段中输入少量空格时,我的所有三个验证都失败了,我困惑为什么它无法通过isNaN
检查。
"" == false // true
和isNaN(" ") // false
Answers:
JavaScript将一个空字符串解释为0,然后失败了isNAN测试。您可以先在字符串上使用parseInt,它不会将空字符串转换为0。然后结果应该为isNAN。
isNaN(arg)
。1)将arg转换为数字,2)检查该数字是否为数值NaN
。这有助于我更好地理解它。
您可能会感到惊讶,也可能不会惊讶,但是这里有一些测试代码向您展示JavaScript引擎的古怪之处。
document.write(isNaN("")) // false
document.write(isNaN(" ")) // false
document.write(isNaN(0)) // false
document.write(isNaN(null)) // false
document.write(isNaN(false)) // false
document.write("" == false) // true
document.write("" == 0) // true
document.write(" " == 0) // true
document.write(" " == false) // true
document.write(0 == false) // true
document.write(" " == "") // false
所以这意味着
" " == 0 == false
和
"" == 0 == false
但
"" != " "
玩得开心 :)
null
,""
和" "
我自己。谢谢!
为了更好地理解它,请打开第43页“ ToNumber应用于字符串类型”的Ecma-Script规范pdf。
如果字符串具有数字语法,可以包含任意数量的空格字符,则可以将其转换为Number类型。空字符串的求值为0。字符串“ Infinity”也应为
isNaN('Infinity'); // false
尝试使用:
alert(isNaN(parseInt(" ")));
要么
alert(isNaN(parseFloat(" ")));
从MDN
您面临问题的原因
当isNaN函数的参数不是Number类型时,该值首先被强制为Number。然后测试结果值以确定它是否为NaN。
您可能需要检查以下全面的答案,其中涵盖了NaN比较是否相等。
如果您想实现一个准确的isNumber函数,可以使用Javascript的一种方法: Douglas Crockford 撰写的The Good Parts [第105页]
var isNumber = function isNumber(value) {
return typeof value === 'number' &&
isFinite(value);
}
Antonio Haley 对此高度评价和接受的答案做出了错误的假设,认为该过程是通过JavaScript parseInt
函数进行的:
您可以在字符串上使用parseInt ...结果应为isNAN失败。
我们可以使用字符串轻松反驳此声明"123abc"
:
parseInt("123abc") // 123 (a number...
isNaN("123abc") // true ...which is not a number)
这样,我们可以看到JavaScript的parseInt
函数返回"123abc"
为number 123
,但是其isNaN
函数告诉我们这"123abc"
不是数字。
ECMAScript-262 isNaN
在第18.2.3节中定义了检查的工作方式。
18.2.3
isNaN
(数量)该
isNaN
功能是%isNaN%
内在的对象。isNaN
使用一个参数编号调用该函数时,将执行以下步骤:
- 放手吧
num
?ToNumber(number)
。- 如果
num
是NaN
,则返回true
。- 否则,返回
false
。
ECMAScript-262的7.1.3节中ToNumber
也定义了它引用的功能。在这里,我们了解了JavaScript如何处理传递给此函数的字符串。
问题中给出的第一个示例是一个只包含空格字符的字符串。本节指出:
阿
StringNumericLiteral
那是空的或仅包含空白转换成+0
。
因此," "
示例字符串将转换为+0
,这是一个数字。
同一部分还指出:
如果语法无法将解释
String
为的扩展StringNumericLiteral
,则的结果ToNumber
为NaN
。
如果不引用该部分中包含的所有检查" x"
,则问题中给出的示例属于上述条件,因为它不能解释为StringNumericLiteral
。" x"
因此被转换为NaN
。
该函数isNaN("")
执行从String到Number 类型的强制转换
ECMAScript 3-5为typeof运算符定义了以下返回值:
最好将我们的测试包装在函数体中:
function isNumber (s) {
return typeof s == 'number'? true
: typeof s == 'string'? (s.trim() === ''? false : !isNaN(s))
: (typeof s).match(/object|function/)? false
: !isNaN(s)
}
此函数不是要测试变量类型,而是测试强制值。例如,布尔值和字符串被强制转换为数字,因此也许您可能想将此函数称为isNumberCoerced()
如果不需要测试string和number以外的其他类型,则以下代码段可用作某些条件的一部分:
if (!isNaN(s) && s.toString().trim()!='') // 's' can be boolean, number or string
alert("s is a number")
这isNaN(" ")
是错误的,isNaN
因为它会将非数字强制转换为数字类型,这是全局函数令人困惑的行为的一部分。
从MDN:
自
isNaN
函数规范的最早版本发布以来,其对非数字参数的行为一直令人困惑。当isNaN
函数的参数不是Number类型时,该值首先被强制为Number。然后测试结果值以确定它是否为NaN
。因此,对于非数字,当将其强制转换为数字类型时会导致产生有效的非NaN数值(尤其是空字符串和布尔基元,当它们被强制数字为零或一时),返回的“ false”可能是意外的;例如,空字符串肯定是“不是数字”。
还请注意,使用ECMAScript 6,现在还有Number.isNaN
方法,根据MDN:
与全局
isNaN()
函数相比,Number.isNaN()
不存在强制将参数转换为数字的问题。这意味着现在可以安全地传递通常会转换为的值NaN
,但实际上与的值不同NaN
。这也意味着仅类型数的值,也就是NaN
returntrue
。
不幸的是:
Number.isNaN
正如博客文章- 修复难看的JavaScript和ES6 NaN问题中概述的那样,甚至ECMAScript 6 方法也有其自身的问题。
该isNaN
函数期望使用Number作为其参数,因此在执行实际的函数逻辑之前,任何其他类型的参数(在您的情况下为字符串)都将转换为Number 。(意识到NaN
也是Number类型的值!)
顺便说一句。这是所有人的共同点内置函数 -如果它们期望某个类型的参数,则将使用标准转换函数来转换实际参数。所有基本类型(布尔型,字符串,数字,对象,日期,空,未定义)之间都有标准转换。
可以使用显式调用String
to 的标准转换。这样我们可以看到:Number
Number()
Number(" ")
评估为 0
Number(" x")
评估为 NaN
鉴于此, isNaN
函数完全合乎逻辑!
真正的问题是为什么标准的字符串到数字的转换像它那样工作。字符串到数字的转换实际上是为了将数字字符串(如“ 123”或“ 17.5e4”)转换为等效数字。转换首先跳过初始空格(因此“ 123”有效),然后尝试将其余部分解析为数字。如果它不可解析为数字(不是“ x”),则结果为NaN。但是有一个明确的特殊规则,即将一个空字符串或仅将空白字符串转换为0。因此可以解释这种转换。
参考:http://www.ecma-international.org/ecma-262/5.1/#sec-9.3.1
我写了这个快速的小功能来帮助解决这个问题。
function isNumber(val) {
return (val != undefined && val != null && val.toString().length > 0 && val.toString().match(/[^0-9\.\-]/g) == null);
};
它只是检查所有不是数字(0-9),不是'-'或'。',不是undefined,null或empty的字符,如果没有匹配项,则返回true。:)
此功能似乎在我的测试中有效
function isNumber(s) {
if (s === "" || s === null) {
return false;
} else {
var number = parseInt(s);
if (number == 'NaN') {
return false;
} else {
return true;
}
}
}
return !(s === "" || s === null || parseInt(s) == 'NaN');
关于什么
function isNumberRegex(value) {
var pattern = /^[-+]?\d*\.?\d*$/i;
var match = value.match(pattern);
return value.length > 0 && match != null;
}
在JavaScript的内置isNaN功能,是-因为默认情况下应预期- “动态型算”。因此,所有的值(在DTC过程中)都可以产生一个简单的true |。的错误,例如"", " ", " 000"
,不能为NaN。
这意味着提供的参数将首先进行如下转换:
function isNaNDemo(arg){
var x = new Number(arg).valueOf();
return x != x;
}
说明:
在函数主体的顶行,我们(首先)试图将自变量成功转换为数字对象。(第二个)使用点运算符-为了我们自己的方便-我们立即剥离所创建对象的原始值。
在第二行中,我们采用在上一步中获得的值,以及NaN不等于宇宙中任何事物,甚至不等于自身的事实这一优势,例如:NaN == NaN >> false
最终将(不平等)它与自身进行比较。
这样,仅当且仅当提供的参数返回是转换为数字对象(即非数字)的失败尝试时,函数返回才会产生true。例如NaN。
isNaNstatic()
但是,对于静态类型运算符-如果需要和需要,我们可以编写一个简单得多的函数,例如:
function isNaNstatic(x){
return x != x;
}
并完全避免使用DTC,以便如果参数不是明确的NaN数字,则它将返回false。因此,请针对以下各项进行测试:
isNaNStatic(" x"); // will return false
因为它仍然是一个字符串。
但是:
isNaNStatic(1/"x"); // will of course return true.
例如isNaNStatic(NaN); >> true
。
但是与相反isNaN
,isNaNStatic("NaN"); >> false
因为它(参数)是一个普通的字符串。
ps:isNaN的静态版本在现代编码方案中非常有用。这很可能是我花时间张贴此文章的主要原因之一。
问候。
isNAN(<argument>)
是判断给定参数是否为非法数字的函数。
isNaN
将参数类型转换为Number类型。如果要检查参数是否为数字?请$.isNumeric()
在jQuery中使用函数。
也就是说,isNaN(foo)等同于isNaN(Number(foo))出于显而易见的原因,它接受所有具有所有数字作为数字的字符串。对于前。
isNaN(123) //false
isNaN(-1.23) //false
isNaN(5-2) //false
isNaN(0) //false
isNaN('123') //false
isNaN('Hello') //true
isNaN('2005/12/12') //true
isNaN('') //false
isNaN(true) //false
isNaN(undefined) //true
isNaN('NaN') //true
isNaN(NaN) //true
isNaN(0 / 0) //true