将<input />值读取为数字而不是字符串(JavaScript)

时间:2010-11-13 19:08:42

标签: javascript json

我们假设页面上有一个文本框:

<input type="text">  

访问者键入了一些字符,我们通过文本框的value属性读取这些字符。

现在,假设文本框代表一个数值。我不能在文本框中定义这样的东西 - 它的值总是一个字符串值。我能做的是,将该sting值转换为数值:

Number(input.value)

但是,输入值被视为 StringNumericLiteral ,而不是 NumericLiteral 。这意味着允许这些输入值(虽然它们不是JavaScript中的数字文字):

  • 带前导零的值(如“000003”)
  • “无限”值
  • 带加号的值(如“+3”)

现在,让我们说 - 为了论证 - 我真的想把输入值读作 NumericLiteral 。我不想要带有前导零或+号等的数字。我在想我怎么能做到这一点,这就是我想出来的:

try  {                  
    var n = JSON.parse('{ "n": ' + this.value + ' }').n;
    if (typeof n !== "number") {
        throw "error";
    }
    // n is a Number value that represents the value of the text-box        
} catch(e) {}

这是代码的简化版本,可在此处获得现场演示:
http://vidasp.net/tinydemos/input-as-number.html

注意:我使用try-catch,因为如果输入值不是有效的JSON值,则JSON.parse调用将失败(抛出错误)。

那么,您如何看待这种方法呢?它有缺陷吗?

(一个缺点是无法读取十六进制数值,因为JSON不允许它们。)

我刚刚意识到......

...我试图这样做的原因并不是将输入实际读作数字。我想要的是检查值是否符合NumericLiteral语法 - 这是正则表达式检查可以轻松完成的事情。

1 个答案:

答案 0 :(得分:4)

使用JSON.parse,您将把您的值作为JSONNumber令牌处理,而不是NumericLiteral

JSONNumberNumericLiteral之间存在差异,JSONNumber不允许前导零(无八进制),也不允许十六进制文字,也不允许前导点(3.)或者相反,一个点后跟小数位数(.3),而且JSON.parse在SpiderMonkey(以及json2.js库){{1}中实现了关于数值的错误不会像人们期望的那样抛出。

您可以进行验证以确保字符串符合JSON.parse('01')语法,如果符合,您可以使用NumericLiteraleval构造函数来真正转换您的值,例如:

Function

用于验证的RegExps来自SourceTextAsen Bozhilov JavaScript实用程序。