parseInt語法: parseInt(string, radix)
之前使用parseInt的時候,大部分都是使用的第一個參數(shù)
比如:
parseInt(10.1) // 10
parseInt('5a') // 5
parseInt('2') // 2
今天看到一道面試題,內(nèi)容為
["1", "2", "3"].map(parseInt)
其解釋為:
首先, map接受兩個參數(shù), 一個回調(diào)函數(shù) callback, 一個回調(diào)函數(shù)的this值
其中回調(diào)函數(shù)接受三個參數(shù) currentValue, index, arrary;
而題目中, map只傳入了回調(diào)函數(shù)--parseInt.
其次, parseInt 只接受兩個兩個參數(shù) string, radix(基數(shù)).
在沒有指定基數(shù),或者基數(shù)為 0 的情況下,JavaScript 作如下處理:
如果字符串 string 以"0x"或者"0X"開頭, 則基數(shù)是16 (16進(jìn)制).
如果字符串 string 以"0"開頭, 基數(shù)是8(八進(jìn)制)或者10(十進(jìn)制),那么具體是哪個基數(shù)由實(shí)現(xiàn)環(huán)境決- 定。ECMAScript 5 規(guī)定使用10,但是并不是所有的瀏覽器都遵循這個規(guī)定。因此,永遠(yuǎn)都要明確給出radix參數(shù)的值。
如果字符串 string 以其它任何值開頭,則基數(shù)是10 (十進(jìn)制)。
所以本題即問
parseInt('1', 0);
parseInt('2',1);
parseInt('3', 2);
首先后兩者參數(shù)不合法.
所以答案是[1, NaN, NaN]
對于前面的說明還是比較理解的,但是對于parseInt第二個參數(shù)的說明就不是很理解了,所以在網(wǎng)上找了一些資料后加深了對該參數(shù)的理解。
我們知道,parseInt方法當(dāng)?shù)诙€參數(shù)不寫時,函數(shù)會嘗試逐個解析字符串中的字符,直到遇上一個無法被解析成數(shù)字的字符,然后返回該字符前所有數(shù)字字符組成的數(shù)字。但是第二個參數(shù)加上后,結(jié)果則可能會完全不一樣。
對于第二個參數(shù),MDN上的解釋是
一個2到36之間的整數(shù)值,用于指定轉(zhuǎn)換中采用的基數(shù)。比如參數(shù)"10"表示使用我們通常使用的十進(jìn)制數(shù)值系統(tǒng)??偸侵付ㄔ搮?shù)可以消除閱讀該代碼時的困惑并且保證轉(zhuǎn)換結(jié)果可預(yù)測。當(dāng)忽略該參數(shù)時,不同的實(shí)現(xiàn)環(huán)境可能產(chǎn)生不同的結(jié)果。如果省略該參數(shù)或其值為 0,則數(shù)字將以 10 為基礎(chǔ)來解析。如果它以 “0x” 或 “0X” 開頭,將以 16 為基數(shù)。如果該參數(shù)小于 2 或者大于 36,則 parseInt() 將返回 NaN。
注:ES5已經(jīng)規(guī)定了如果省略第二個參數(shù)就代表用十進(jìn)制解析。
所以對于第二個參數(shù)的理解,其實(shí)就可以理解為"進(jìn)制",比如第二個參數(shù)為2,則為二進(jìn)制,3則為三進(jìn)制,16則為十六進(jìn)制等等。
而我們進(jìn)制的計(jì)算公式為:
xyz(n) = x*n^2 + y*n^1 + z
比如二進(jìn)制:
12 = 5
計(jì)算方法:1*2^1 + 2*2^0 = 5
三進(jìn)制
21 = 7
計(jì)算方法:2*3^1 + 1*2^0 = 7
那么對于上面的問題就比較好理解了
parseInt('1',0); // 十進(jìn)制,結(jié)果則為1
parseInt('2',1); // 一進(jìn)制,最大為0,那么2就會不被解析,那就會變成NaN
parseInt('3',2); // 二進(jìn)制,最大為1,那么3就會不被解析,那就會變成NaN
特別說明
我們前面用到的radix全部都是10以內(nèi)的,那么最大就是十進(jìn)制時的數(shù)字9,我們知道,radix的范圍是2~36,在解析的過程中遇到無法被解析成數(shù)字的字符,就會返回該字符前所有數(shù)字字符組成的數(shù)字,那么當(dāng)radix大于10的時候呢?這個時候就會和前面有所差異了,比如radix為11,即十一進(jìn)制時,最大的數(shù)字就變成了兩位數(shù),這樣肯定是不行的,所以從10以后,就開始用字母代替,比如 a = 10,b = 11,c = 12,...z=35,這也就能解釋為什么radix的范圍是2~36了。
所以:parseInt('dasff66',16) 的結(jié)果是多少呢?
在16進(jìn)制中,最大的數(shù)字是15,對應(yīng)字母也就是f,超過f的字母也就超出了16進(jìn)制的解析范圍。
'dasff66'的第一個字符是d,也就是十進(jìn)制中的13,第二個字符是a,也就是十進(jìn)制10,第三個字符s,代表十進(jìn)制中的28,這顯然超出了16進(jìn)制的解析范圍,所以s和它之后的字符都會被parseInt自動忽略,所以我們得到結(jié)果為:
13 * 16^1 + 10 * 16^0 = 218
至此,對于parseInt的第二個參數(shù)已經(jīng)有了全面的了解,后面再遇到類似的問題也能夠有明確的解題思路了。
PS:注意下,另一個函數(shù)parseFloat只接受一個參數(shù),只能使用十進(jìn)制去解析。