题
我有一个简单的问题(我希望!).在JS,为什么 isNaN(" ")
评估,以虚假的,但是 isNaN(" x")
评估,真的吗?
我执行的数字操作上的一个文本输入域,并检查,如果领域是null,"",或楠。当有人类少数的空间进入外地,我的验证在所有三个,并且我困惑为什么它得到过去的isNAN检查。
谢谢!
解决方案
JavaScript将空字符串解释为0,然后无法通过isNAN测试。你可以先在字符串上使用parseInt,它不会将空字符串转换为0.结果应该是失败的isNAN。
其他提示
您可能会发现这个令人惊讶或者可能没有,但这里有一些测试代码可以向您展示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
但是
"" != " "
玩得开心:)
为了更好地理解,请打开 Ecma-Script spec pdf on page 43“ToNumber applied to the String Type”
如果字符串具有数字语法,可以包含任意数量的空格字符,则可以将其转换为数字类型。空字符串的计算结果为0.此外,字符串'Infinity'应该给出
isNaN('Infinity'); // false
尝试使用:
alert(isNaN(parseInt(" ")));
或者
alert(isNaN(parseFloat(" ")));
来自 MDN
您面临的问题的原因
当isNaN函数的参数不是Number类型时,该值首先被强制转换为Number。然后测试结果值以确定它是否是NaN。
您可能需要查看以下全面的答案,其中包含NaN对比的平等性。
我认为这是因为Javascript的输入:''
转换为零,而'x'
不是:
alert(' ' * 1); // 0
alert('x' * 1); // NaN
如果你想实现一个准确的isNumber函数,这里有一种方法可以通过Douglas Crockford的 Javascript:The Good Parts 进行[第105页]
var isNumber = function isNumber(value) {
return typeof value === 'number' &&
isFinite(value);
}
不完全正确的答案
Antonio Haley的高度赞成和接受的答案在此做出错误的假设,即此过程通过JavaScript的 parseInt
function:
你可以在字符串上使用parseInt ......结果应该是失败的是NAN。
我们可以使用字符串" 123abc"
轻松反驳此声明:
parseInt("123abc") // 123 (a number...
isNaN("123abc") // true ...which is not a number)
有了这个,我们可以看到JavaScript的 parseInt
函数返回" 123abc"
作为数字 123
,但它的是NaN
函数告诉我们" 123abc"
不是一个数字。
正确答案
ECMAScript-262定义 isNaN
检查如何在第18.2.3节。
18.2.3
isNaN
(Number)
isNaN
函数是%isNaN%
内在对象。当使用一个参数号调用isNaN
函数时,将执行以下步骤:
- 让
num
成为? <代码> ToNumber(数)代码>- 如果
num
是NaN
,请返回true
。- 否则,请返回
醇>false
。
它引用的 ToNumber
函数也在 ECMAScript-中定义。 262第7.1.3节。在这里,我们了解JavaScript如何处理传入此函数的字符串。
问题中给出的第一个示例是一个只包含空格字符的字符串。本节说明:
StringNumericLiteral
为空或仅包含空格,将转换为+0
。
&quot;因此,
示例字符串将转换为 +0
,这是一个数字。
同一部分还指出:
如果语法不能将
String
解释为StringNumericLiteral
的扩展,那么ToNumber
的结果是NaN
在不引用该部分中包含的所有检查的情况下,&quot;问题中给出的x“
示例属于上述条件,因为它不能被解释为 StringNumericLiteral
。 <代码>&QUOT;因此,x&quot; 转换为 NaN
。
我不确定为什么,但为了解决这个问题,您可以在检查前始终修剪空白。无论如何,你可能想要这样做。
功能 isNaN("")
执行 串数字 类型的胁迫
- 不确定
- 目(null,对象,阵列)
- 布尔
- 数量
- 字符串
- 功能
更好的包裹我们测试一个函数的身体:
function isNumber (s) {
return typeof s == 'number'? true
: typeof s == 'string'? (s.trim() === ''? false : !isNaN(s))
: (typeof s).match(/object|function/)? false
: !isNaN(s)
}
这一功能是不intented测变量 类型, 相反,它测试 强迫值.例如,布尔和串被迫到数字,因此,也许你可以想要称呼这个功能 isNumberCoerced()
如果没有需要测试 类型 其他比 字符串 和 数量, 然后下面的段可能会被用作一部分的一些条件:
if (!isNaN(s) && s.toString().trim()!='') // 's' can be boolean, number or string
alert("s is a number")
如果您真的想要检查它是否为整数,我建议您使用以下函数:
function isInteger(s)
{
return Math.ceil(s) == Math.floor(s);
}
isNaN(&quot;&quot;)
为false是 isNaN
全局函数混淆行为的一部分,因为它将非数字强制转换为数字类型
来自 MDN :
由于
isNaN
函数规范的最早版本,其非数字参数的行为一直令人困惑。当isNaN
函数的参数不是Number类型时,该值首先被强制转换为Number。然后测试结果值以确定它是否是NaN
。因此,对于非数字,当被强制为数字类型时导致有效的非NaN数值(特别是空字符串和布尔基元,当被强制给出数值0或1时),则为“假”。返回值可能是意外的;例如,空字符串肯定是“不是数字”。
另请注意,对于ECMAScript 6,现在还有 Number.isNaN
方法,根据MDN:
与全局
isNaN()
函数相比,Number.isNaN()
不会遇到强制将参数转换为数字的问题。这意味着现在可以安全地传递通常转换为NaN
的值,但实际上与NaN
的值不同。这也意味着只有类型编号的值(也是NaN
)才会返回true
。
<强>不幸的是强>:
即使ECMAScript 6 Number.isNaN
方法也有自己的问题,如博客文章中所述 - 修复丑陋的JavaScript和ES6 NaN问题。
正如其他人所解释的那样, isNaN
函数会在验证之前将空字符串强制转换为数字,从而将空字符串更改为0(这是一个有效数字)。
但是,我发现 parseInt
函数在尝试解析空字符串或仅包含空格的字符串时将返回 NaN
。因此,以下组合似乎运作良好:
if(isNaN(string)|| isNaN(parseInt(string)))console.log('not a number!');
此检查适用于正数,负数和带小数点的数字,因此我认为它涵盖了所有常见的数字情况。
这个功能似乎在我的测试中起作用
function isNumber(s) {
if (s === "" || s === null) {
return false;
} else {
var number = parseInt(s);
if (number == 'NaN') {
return false;
} else {
return true;
}
}
}
怎么样?
function isNumberRegex(value) {
var pattern = /^[-+]?\d*\.?\d*$/i;
var match = value.match(pattern);
return value.length > 0 && match != null;
}
的 isNaN
功能预计数作为其参数,以参数的任何其他类型(在你的情况一string)将转换为数 之前 实际逻辑功能是进行。(注意, NaN
也是一个值的型号!)
顺便说一句.这是很常见的 所有 建立功能-如果他们期望一个参数的一个某些类型、实际的参数,将转换为使用标准的转换功能。有标准之间的转换的所有基本类型(bool、串号码,目的,日期,null,不确定的。)
标准转化为 String
要 Number
可以援用明确 Number()
.因此,我们可以看到:
Number(" ")
计算结果为0
Number(" x")
计算结果为NaN
有鉴于此,结果的 isNaN
功能的完全合乎逻辑的!
真正的问题是为什么标准字符串到-数转换工作的喜欢它。串到-数转换是真正的旨在转换为数字串像"123"或"17.5e4"相当于数字。转换第一跳过最初的空白(所"123"是有效的),然后试图分析在于作为一个数字。如果它不是可解析的,作为一个数字("x"是不是),则结果是楠。但是有明显特殊规则,一串其是空的或唯一的空白被转变为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)的任何字符,它们不是' - '或'。',并且不是未定义的,null或为空,如果没有匹配则返回true。 :)
内置 isNaN 功能的 JavaScript 是 - 默认情况下应该预期的 - “动态类型操作员”。
因此,(在DTC过程中)所有的值都可能产生一个简单的真值false,例如&quot;&quot;,&quot; “,” 000“
,不能是NaN。
意味着提供的参数将首先进行转换,如下所示:
function isNaNDemo(arg){
var x = new Number(arg).valueOf();
return x != x;
}
<强>解释强>
在函数体的顶行,我们(首先)尝试将参数成功转换为数字对象。并且(第二),使用点运算符 - 为了我们自己的方便 - 立即剥离,创建对象的原始值。
在第二行中,我们将获取上一步中获得的值,以及 NaN 与Universe中的任何内容不相等的优势,甚至不是自己,例如: NaN == NaN&gt;&gt; false
最后将它(对于不等式)与自身进行比较。
这样,只有在提供的参数返回失败尝试转换为数字对象时,函数返回才会产生 true ,即,一个非数字号码;例如,NaN。
isNaNstatic()
但是,对于静态类型运算符 - 如果需要并且在需要时 - 我们可以编写一个更简单的函数,例如:
function isNaNstatic(x){
return x != x;
}
完全避免使用DTC,这样如果参数不是明确的NaN号,它将返回false。因此,测试以下内容:
isNaNStatic(&quot; x&quot;); //将返回false
,因为它仍然是一个字符串。
然而:
<代码> isNaNStatic(1 /英寸×&QUOT); //当然会返回true。,例如 isNaNStatic(NaN); &GT;&GT;真代码>。
但与 isNaN
相反, isNaNStatic(&quot; NaN&quot;); &GT;&GT; false
因为它(参数)是一个普通的字符串。
P.S .: isNaN的静态版本在现代编码场景中非常有用。这可能是我花时间发布这个的主要原因之一。
问候。
isNAN(&lt; argument&gt;)
是一个判断给定参数是否为非法数字的函数。
isNaN
将参数类型化为Number类型。如果要检查参数是否为数字?请在jQuery中使用 $ .isNumeric()
函数。
也就是说,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
我用这个
function isNotANumeric(val) {
if(val.trim && val.trim() == "") {
return true;
} else {
return isNaN(parseFloat(val * 1));
}
}
alert(isNotANumeric("100")); // false
alert(isNotANumeric("1a")); // true
alert(isNotANumeric("")); // true
alert(isNotANumeric(" ")); // true
NaN
!==&quot;不是数字“
NaN
是数字类型
这是ECMAScript
中isNaN()的定义1. Let num be ToNumber(number).
2. ReturnIfAbrupt(num).
3. If num is NaN, return true.
4. Otherwise, return false.
尝试将任何值转换为数字。
Number(" ") // 0
Number("x") // NaN
Number(null) // 0
如果要确定值是否为 NaN
,则应首先尝试将其转换为Number值。
检查某些字符串值是否带有空格或&quot; “
是 isNaN
可能尝试执行字符串验证,例如:
// value =&quot; 123&quot;
if(value.match(/ \ s /)|| isNaN(value)){
// 做一点事
} 代码>