zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    zoj 3279 线段树 OR 树状数组
    fzu 1962 树状数组 OR 线段树
    hdu 5057 块状链表
    hdu3487 Play with Chain
    bzoj 1588营业额统计(HNOI 2002)
    poj2823 Sliding Window
    poj2828 Buy Tickets
    poj2395 Out of Hay
    poj3667 Hotel
    poj1703 Lost Cows
  • 原文地址:https://www.cnblogs.com/snandy/p/3726512.html
Copyright © 2011-2022 走看看