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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM