我最近遇到了一段非常像这样的代码:
var nHours = parseInt(txtHours);
if( isNaN(nHours)) // Do something
else // Do something else with the value
编写此代码的开发人员认为nHours
可能是与txtHours
或NaN
完全匹配的整数。这个假设有几个问题。
首先,radix参数左侧的开发人员意味着"09"
的输入将导致值0
而不是9
。这个问题可以通过添加基数来解决:
var nHours = parseInt(txtHours,10);
if( isNaN(nHours)) // Do something
else // Do something else with the value
接下来,"1.5"
的输入将导致值1
而不是NaN
,这不是开发人员预期的,因为1.5
不是整数。同样,"1a"
的值将导致值1
而不是NaN
。
所有这些问题都是可以理解的,因为这是如何将字符串转换为整数的最常见示例之一,大多数地方都不讨论这些情况。
无论如何,它让我觉得我不知道有任何内置的方法来获得这样的整数。有Number(txtHours)
(或+txtHours
)更接近但接受非整数,并将null
和""
视为0而不是NaN
。
为了帮助开发人员,我提供了以下功能:
function ConvertToInteger(text)
{
var number = Math.floor(+text);
return text && number == text ? number : NaN;
}
这似乎涵盖了上述所有问题。有没有人知道这种技术有什么问题,或者可能是一种更简单的方法来获得相同的结果?
答案 0 :(得分:3)
这就是我想出的:
function integer(x) {
if (typeof x !== "number" && typeof x !== "string" || x === "") {
return NaN;
} else {
x = Number(x);
return x === Math.floor(x) ? x : NaN;
}
}
(注意:我更新了此功能以防范白色空间字符串。请参阅下文。)
这个想法是只接受类型为Number或String(但不是空字符串值)的参数。然后转换为Number(如果它是一个字符串),最后将其值与floor()值进行比较,以确定该数字是否为整数。
integer(); // NaN
integer(""); // NaN
integer(null); // NaN
integer(true); // NaN
integer(false); // NaN
integer("1a"); // NaN
integer("1.3"); // NaN
integer(1.3); // NaN
integer(7); // 7
但是,NaN值在这里被“误用”,因为浮点数和表示浮点数的字符串会导致NaN,这在技术上并不正确。
另请注意,由于字符串转换为数字的方式,字符串参数可能具有尾随或前导空格或前导零:
integer(" 3 "); // 3
integer("0003"); // 3
另一种方法......
如果输入值是字符串,则可以使用正则表达式。
此正则表达式:/^\s*(\+|-)?\d+\s*$/
将匹配表示整数的字符串。
更新功能!
function integer(x) {
if ( typeof x === "string" && /^\s*(\+|-)?\d+\s*$/.test(x) ) {
x = Number(x);
}
if ( typeof x === "number" ) {
return x === Math.floor(x) ? x : NaN;
}
return NaN;
}
这个版本的integer()更严格,因为它只允许遵循某种模式的字符串(使用正则表达式进行测试)。它产生与其他integer()函数相同的结果,除了它另外忽略所有空格字符串(如@CMS所指出的)。
再次更新!
我注意到了@Zecc的答案并简化了代码......我想这也有效:
function integer(x) {
if( /^\s*(\+|-)?\d+\s*$/.test(String(x)) ){
return parseInt(x, 10);
}
return Number.NaN;
}
它可能不是最快的解决方案(在性能方面),但我喜欢它的简单性:)
答案 1 :(得分:1)
这是我的尝试:
function integer(x) {
var n = parseFloat(x); // No need to check typeof x; parseFloat does it for us
if(!isNaN(n) && /^\s*(\+|-)?\d+\s*$/.test(String(x))){
return n;
}
return Number.NaN;
}
我必须将ŠimeVidas归功于正则表达式,尽管我会亲自到达那里。
修改:我不知道全球有NaN
个。我一直使用Number.NaN
生活和学习。
答案 2 :(得分:1)
我的解决方案涉及一些廉价的技巧。它基于以下事实:Javascript中的位运算符将其操作数转换为整数。
我不太确定表示整数的字符串是否应该起作用,所以这里有两种不同的解决方案。
function integer (number) {
return ~~number == number ? ~~number : NaN;
}
function integer (number) {
return ~~number === number ? ~~number : NaN;
}
第一个将使用整数作为字符串,第二个不会。 按位非(〜)运算符将其操作数转换为整数。 对于整数较大的整数,此方法失败,无法用32位宽的整数表示(-2147483647 ... 2147483647)表示。
答案 3 :(得分:-1)
您可以先将String转换为Integer,然后再转换回String。然后检查第一个和第二个字符串是否匹配。
编辑:我的意思的一个例子:
function cs (stringInt) {
var trimmed = stringInt.trim(); // trim original string
var num = parseInt(trimmed, 10); // convert string to integer
newString = num + ""; // convert newly created integer back to string
console.log(newString); // (works in at least Firefox and Chrome) check what's new string like
return (newString == trimmed); // if they are identical, you can be sure that original string is an integer
}
如果您输入的字符串实际上是整数,则此函数将返回true。如果您不想修剪,可以修改它。使用前导零将失败,但是,如果您愿意,可以再次在此函数中删除它们。这样,您不需要使用NaN
或正则表达式,您可以轻松检查字符串整数的有效性。