• IE6/7/8中parseInt第一个参数为非法八进制字符串且第二个参数不传时返回值为0


    JavaScript中数字有十进制、八进制、十六进制。以"0"开头的是八进制,"0x"或"0X"开头的是十六进制。

    parseInt用来把字符串转换成整型数字,它接受两个参数,第一个参数为字符串,第二个为数字基数如8,10,16。

    parseInt(string, radix)

    当第二个参数不传时默认为10,即默认转成十进制的数字。

    parseInt('7')   // number 7
    parseInt('8')   // number 8
    parseInt('9')   // number 9
    

    这三行代码在所有浏览器中都表现一致。

    但第一个参数如果所传的是非法八进制数字,且第二个参数不传时,IE6/7/8将返回0,其它浏览器会忽略0返回,返回0后的数字。

    parseInt('08') // IE678返回0,其它浏览器返回8
    parseInt('09') // IE678返回0,其它浏览器返回9
    

    0开头的为八进制,八进制只有0-7,"08", "09"显然是非法的八进制形式。IE6/7/8中返回的是0, 其它浏览器是8,9。

    当然,如果是合法的八进制形式,IE6/7/8处理和其它浏览器一致,如

    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

    var isIE678 = parseInt('08') === 0;
    

       

    除此之外,parseInt有一下特征(所有浏览器都一样)

    一、radix 不传或为假值时,默认按10进制处理 (JS六个假值)

    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
    

    二、默认会忽略左右空白符

    alert(parseInt(' 9')) // 9
    alert(parseInt('9 ')) // 9
    alert(parseInt(' 9 ')) // 9
    

      

    三、但不会去掉中间的空白符,且默认忽略中间空白符后所有的字符

    alert(parseInt('9 0')) // 9
    alert(parseInt(' 9 0 ')) // 9
    alert(parseInt(' 9 a ')) // 9

    四,以"0x"或"0X"开头的字符串一律按16进制处理,无论第二个参数radix传或不传或任意值

    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

  • 相关阅读:
    MFC半透明对话框
    关于.h .lib .dll的总结
    C# 调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配
    LeetCode——011 Container With Most Water
    《Effective C++》——读书笔记
    《More Effective C++》——读书笔记
    Chrome插件推荐
    LeetCode——004-Median-of-Two-Sorted-Arrays
    《STL源码剖析》——第七、八章:仿函数与接配器
    《STL源码剖析》——第五、六:关联容器与算法
  • 原文地址:https://www.cnblogs.com/snandy/p/3726512.html
Copyright © 2020-2023  润新知