[点晴永久免费OA]js parseInt之0.0000001陷阱分析小结【javascript】
当前位置:点晴教程→点晴OA办公管理信息系统
→『 经验分享&问题答疑 』
:我的费用报销申请单金额自动计算多了0.0000001,不知道多的 0.0000001 怎么来的,计算总数字没错,我检查了JS也没问题。 : js parseInt的陷阱分析小结,当第一个字符为0时,Js会把它看成一个8进制数字,其他8进制之外的字符都回被忽略掉。 var a = parseInt("09"), b = Number("09"); 很多人会认为a和b的值都是数字9,但实际上不是。 parseInt的主要作用是把字符串转换为整数,或者把小数转换为整数。一般情况下,我们只用到它的第一个参数。但实际上,它有两个参数: parseInt(string, radix) parseInt会根据radix指定的进制进行转换,比如: alert(parseInt("10", 2)); // outputs '2' 在没有指定radix或者radix为0的情况下,parseInt会按十进制进行转换。然而,这在某些情况下有点特殊: * 如果string的值以“0x”开头,parseInt会按十六进制进行转换; * 如果string的值以“0”开头,parseInt会按八进制进行转换。 说回开头的代码,由于"09"是以“0”开头,所以parseInt会按八进制进行转换,但是“9”不是合法的八进制值(八进制只有0-7八个数字),所以转换结果是0。 要避免这个陷进,可以强制指定radix: alert(parseInt("09", 10)); // outputs '9' 其它网友的补充: 看代码: alert(parseInt(0.000001)); alert(parseInt(0.0000001)); 第一条语句输出 0, 第二条语句输出 1, 囧。 继续看代码: alert(parseInt('0.000001')); alert(parseInt('0.0000001')); 都输出 0, 这才符合预期。 查看 ECMA-262 规范,parseInt 会先调用 toString 方法。问题已逐渐清晰: alert(0.000001); alert(0.0000001); 第一条语句原样输出,第二条语句输出 1e-7. 继续翻查 ECMA-262 9.8.1 ToString Applied to the Number Type 一节,恍然大悟: assertEquals("0.00001", (0.00001).toString()); assertEquals("0.000001", (0.000001).toString()); assertEquals("1e-7", (0.0000001).toString()); assertEquals("1.2e-7", (0.00000012).toString()); assertEquals("1.23e-7", (0.000000123).toString()); assertEquals("1e-8", (0.00000001).toString()); assertEquals("1.2e-8", (0.000000012).toString()); 上面是 V8 引擎 number-tostring 的单元测试脚本, 很好地诠释了 ECMA 规范。 小结:对于小于 1e-6 的数值来说,ToString 时会自动转换为科学计数法。因此 parseInt 方法,在参数类型不确定时,最好封装一层: function parseInt2(a) { if(typeof a === 'number') { return Math.floor(a); } return parseInt(a); } Javascript有两种数据类型的转换方法: 一种是将整个值从一种类型转换为另一种数据类型(称作基本数据类型转换), 另一种方法是从一个值中提取另一种类型的值,并完成转换工作。 基本数据类型转换的如以下三种方法: 1.转换为字符型:String(); 例:String(678)的结果为"678" 2.转换为数值型:Number(); 例:Number("678")的结果为678 3.转换为布尔型:Boolean(); 例:Boolean("aaa")的结果为true 从一个值中提取另一种类型的值的如以下方法: 1.提取字符串中的整数:parseInt(); 例:parseInt("123zhang")的结果为123 2.提取字符串中的浮点数:parseFloat(); 例:parseFloat("0.55zhang")的结果为0.55 另外总结各种类型转换的方法 Number转化成字符串:String(number)、 Number.toString(2/8/16);//分别代表二进制\八进制\十六进制默认(无参)10进制 Number.toFixed(3) //保留小数点后3位 Number.toExponextial(3); //小数点前1位、小数点后3位,如var n=123456.789; n.toExponextial(3);//1.234e+5即1.234X105 Number.toPrecision(4); //返回指定位数 如果位数不够完全显示,则按指数表示法(3个方法都会4舍5入) 该文章在 2015/3/9 16:15:29 编辑过 |
关键字查询
相关文章
正在查询... |