看完標題,入坑過的同窗腦海裏很快會浮現出這道經典面試題,沒碰到過的同窗不妨跟着樓主先來複習一遍 parseInt 的用法(主要參考 MDN)。javascript
parseInt 是 JavaScript 中的一個全局函數(頂級函數),它會將給定的字符串以指定基數(radix/base)解析成爲整數。java
它的語法很是簡單:面試
parseInt(string, radix)
第一個參數 string 是要被解析的值,若是參數不是一個字符串,則將其轉換爲字符串,字符串開頭的空白符將會被忽略。而第二個參數 radix 是一個 2 到 36 之間的整數值,用於指定轉換中採用的基數,若是不傳入,默認是 10,即按照十進制轉換,這裏要注意一點,若是第二個參數傳入 0,和傳入 10 以及不傳入第二個參數等效。函數返回一個整數值,若是解析過程當中發生錯誤,將返回 NaN。數組
返回 NaN 的主要有如下幾種狀況:函數
console.log(parseInt('hello', 2)); // NaN console.log(parseInt('3', 2)); // NaN, 3 不是合法的二進制數字 console.log(parseInt('3', 100)); // NaN
其實實際開發中我不多用 parseInt,而是用 +
和 ~~
代替,由於它實在是太長了,可是很顯然 parseInt 的使用範圍更廣。prototype
簡單回顧了 parseInt 的用法,咱們來看這道題:code
let ans = ["1", "2", "3"].map(parseInt); console.log(ans);
和大多數人同樣,個人第一反應也是返回 [1, 2, 3]
,這個時候咱們有必要回顧下 Array.prototype.map
,該方法的參數是一個函數,而該函數又能夠接受三個參數,分別表示數組元素的值,數組元素的在數組中的索引,以及對於數組的引用。通常來講咱們直接在 map 方法中傳入匿名函數,可是若是這個函數是在外面定義的,傳入的是方法名呢?索引
let fn = (...a) => { console.log(a); }; let ans = ["1", "2", "3"].map(fn); // [ '1', 0, [ '1', '2', '3' ] ] // [ '2', 1, [ '1', '2', '3' ] ] // [ '3', 2, [ '1', '2', '3' ] ]
咱們能夠看到,若是沒爲該函數指定參數,那麼這三個參數都會被傳入!ip
咱們再回到這道題,parseInt 方法是能夠傳入 1-2 個參數的,因此 map 傳入的三個參數,實際上是都會被傳給 parseInt 方法的,只是 parseInt 會使用前兩個參數而已。開發
console.log(parseInt('12', 10, 'ignore')); // 12
因此整個過程差很少是這樣的:
let fn = (item, index, array) => { return parseInt(item, index, array); }; let ans = ["1", "2", "3"].map(fn); console.log(ans); // [ 1, NaN, NaN ]
其實就是計算以下:
console.log(parseInt("1", 0)); // 1 console.log(parseInt("2", 1)); // NaN console.log(parseInt("3", 2)); // NaN
看懂了吧不妨再試試下面這道:
let ans = "1 2 3".replace(/\d/g, parseInt); console.log(ans);
原理是同樣的,當 replace 的第二個參數是函數的時候,該函數的第一個參數是匹配模式的字符串,接下來的參數是與模式中的子表達式匹配的字符串,能夠有 0 個或者多個這樣的參數。接下來的參數是一個整數,聲明瞭匹配在 StringObject 中出現的位置,最後一個參數是 StringObject 自己。
仍是同樣,打印出來看看唄:
let fn = (...a) => { console.log(a); }; let ans = "1 2 3".replace(/\d/g, fn); // [ '1', 0, '1 2 3' ] // [ '2', 2, '1 2 3' ] // [ '3', 4, '1 2 3' ]
接下去就簡單了,就是計算下面的表達式了:
console.log(parseInt("1", 0, '1 2 3')); // 1 console.log(parseInt("2", 2, '1 2 3')); // NaN console.log(parseInt("3", 4, '1 2 3')); // 3
最後再加一道題:
console.log(parseInt(Infinity, 19))
前面說了,第一個參數 string 是要被解析的值,若是參數不是一個字符串,則將其轉換爲字符串,因此 Infinity 被轉換成 "Infinity",而 19 進制數中,最大的字符就是 i,表明 18,因此解析的時候遇到 n 就停了,因此輸出 18