我们假设页面上有一个文本框:
<input type="text">
访问者键入了一些字符,我们通过文本框的value
属性读取这些字符。
现在,假设文本框代表一个数值。我不能在文本框中定义这样的东西 - 它的值总是一个字符串值。我能做的是,将该sting值转换为数值:
Number(input.value)
但是,输入值被视为 StringNumericLiteral ,而不是 NumericLiteral 。这意味着允许这些输入值(虽然它们不是JavaScript中的数字文字):
现在,让我们说 - 为了论证 - 我真的想把输入值读作 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语法 - 这是正则表达式检查可以轻松完成的事情。
答案 0 :(得分:4)
使用JSON.parse
,您将把您的值作为JSONNumber
令牌处理,而不是NumericLiteral
。
JSONNumber
和NumericLiteral
之间存在差异,JSONNumber
不允许前导零(无八进制),也不允许十六进制文字,也不允许前导点(3.
)或者相反,一个点后跟小数位数(.3
),而且JSON.parse
在SpiderMonkey(以及json2.js库){{1}中实现了关于数值的错误不会像人们期望的那样抛出。
您可以进行验证以确保字符串符合JSON.parse('01')
语法,如果符合,您可以使用NumericLiteral
或eval
构造函数来真正转换您的值,例如:
Function
用于验证的RegExps来自SourceText的Asen Bozhilov JavaScript实用程序。