關於 parseInt 的一道有意思的面試題

看完標題,入坑過的同窗腦海裏很快會浮現出這道經典面試題,沒碰到過的同窗不妨跟着樓主先來複習一遍 parseInt 的用法(主要參考 MDN)。javascript

parseInt 是 JavaScript 中的一個全局函數(頂級函數),它會將給定的字符串以指定基數(radix/base)解析成爲整數。java

它的語法很是簡單:面試

parseInt(string, radix)

第一個參數 string 是要被解析的值,若是參數不是一個字符串,則將其轉換爲字符串,字符串開頭的空白符將會被忽略。而第二個參數 radix 是一個 2 到 36 之間的整數值,用於指定轉換中採用的基數,若是不傳入,默認是 10,即按照十進制轉換,這裏要注意一點,若是第二個參數傳入 0,和傳入 10 以及不傳入第二個參數等效。函數返回一個整數值,若是解析過程當中發生錯誤,將返回 NaN。數組

返回 NaN 的主要有如下幾種狀況:函數

  • 被解析參數的第一個字符沒法被轉化成數值類型
  • 被解析參數數值太大,不是 radix 進制下的合法數字
  • radix 不在 [2, 36] 範圍內(注意其實 0 也是能夠的)
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

相關文章
相關標籤/搜索