IE6/7/8中parseInt第一个参数为非法八进制字符串且第二个参数不传时返回值为0
JavaScript中数字有十进制、八进制、十六进制。以"0"开头的是八进制,"0x"或"0X"开头的是十六进制。
parseInt用来把字符串转换成整型数字,它接受两个参数,第一个参数为字符串,第二个为数字基数如8,10,16。
1 | parseInt(string, radix) |
当第二个参数不传时默认为10,即默认转成十进制的数字。
1 2 3 | parseInt( '7' ) // number 7 parseInt( '8' ) // number 8 parseInt( '9' ) // number 9 |
这三行代码在所有浏览器中都表现一致。
但第一个参数如果所传的是非法八进制数字,且第二个参数不传时,IE6/7/8将返回0,其它浏览器会忽略0返回,返回0后的数字。
1 2 | parseInt( '08' ) // IE678返回0,其它浏览器返回8 parseInt( '09' ) // IE678返回0,其它浏览器返回9 |
0开头的为八进制,八进制只有0-7,"08", "09"显然是非法的八进制形式。IE6/7/8中返回的是0, 其它浏览器是8,9。
当然,如果是合法的八进制形式,IE6/7/8处理和其它浏览器一致,如
1 2 | parseInt( '01' ) // 1 parseInt( '07' ) // 7 |
这应该算IE6/7/8的bug,IE9+的处理已经和Firefox/Chrome一致了。看下ES3规范
当radix为undefined或0时,且string不是以0x或0X开头则按十进制处理。显然,'08', '09'不是以 '0x' 或 '0X' 开头。IE6/7/8按八进制处理,8,9是非法的八进制数字,引擎忽略返回了0。
可以利用这个特性判断浏览器是否是IE6,7,8
1 | var isIE678 = parseInt( '08' ) === 0; |
除此之外,parseInt有一下特征(所有浏览器都一样)
一、radix 不传或为假值时,默认按10进制处理 (JS六个假值)
1 2 3 4 5 6 7 | alert(parseInt( '9' )) // 9 alert(parseInt( '9' , null )) // 9 alert(parseInt( '9' , undefined)) // 9 alert(parseInt( '9' , 0)) // 9 alert(parseInt( '9' , '' )) // 9 alert(parseInt( '9' , NaN)) // 9 alert(parseInt( '9' , false )) // 9 |
二、默认会忽略左右空白符
1 2 3 | alert(parseInt( ' 9' )) // 9 alert(parseInt( '9 ' )) // 9 alert(parseInt( ' 9 ' )) // 9 |
三、但不会去掉中间的空白符,且默认忽略中间空白符后所有的字符
1 2 3 | alert(parseInt( '9 0' )) // 9 alert(parseInt( ' 9 0 ' )) // 9 alert(parseInt( ' 9 a ' )) // 9 |
四,以"0x"或"0X"开头的字符串一律按16进制处理,无论第二个参数radix传或不传或任意值
1 2 3 4 5 6 7 | alert(parseInt( '0xa' )) // 10 alert(parseInt( '0xa' ), 8) // 10 alert(parseInt( '0xa' ), 16) // 10 alert(parseInt( '0Xa' )) // 10 alert(parseInt( '0Xa' ), 8) // 10 alert(parseInt( '0Xa' ), 16) // 10 |
最后附上ES5里parseInt的伪码实现 (parseInt 内部执行流程)
1 调用toString(string) ,即先把第一个参数转成字符串。
2 去掉string的两边空白符,赋值给S,如果 S 不包含一个字符,那么令S为空字符串。
3 令 sign = 1
4 如果 S 不是一个空字符串,且第一个字符为负号 "-", sign赋值为-1。
5 如果 S 不是一个空字符串,且第一个字符为正号 "+" 或负号 "-",去掉正负号。如 "+30" 变为了"30", "-30"变为"30"。
6 令 R = ToInt32(radix)
7 stripPrefix = true
8 R不为0时,如果 R < 2 或 R > 36,直接返回NaN,如果 R != 16,令 stripPrefix = false
9 R为0时,令 R = 10
10 stripPrefix为true时, 如果 S 的长度length大于2切前两个字符是"0x"或"0X",那么去掉 S 的前两个字符("0x"|"0X"),令R = 16。
11 如果 S 包含的任意字符不是一个有效的 radix-R 数字(比如"8"就不是一个有效的八进制数字),令 Z 为非有效进制数字前的字符,否则令 Z = S。
12 如果 Z 是一个空字符串,返回NaN。
13 令 mathInt 为由字符串 Z 指定的 radix-R进制的数字,使用A-Z和a-z替代数字10-35。
14 令 number 为数字类型的mathInt
15 返回 sign*number
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端