parseInt
的函數簽名/** * Converts a string to an integer. * @param s 要被解析的值。若是參數不是一個字符串,則將其轉換爲字符串(使用 ToString 抽象操做)。字符串開頭的空白符將會被忽略。 * @param radix 一個介於2和36之間的整數(數學系統的基礎),表示上述字符串的基數。 * 若是不提供這個參數,以 `0x` 開頭的字符串會被識別成16進制數. * 其它狀況,不一樣環境有不一樣的處理方式,通常會被識別成10進制數 * 若是傳入 0 null undefined 等,當不提供這個參數處理 * 若是傳入不是數字的會把數字,會把參數轉成數字,若是無法轉化,當不提供這個參數處理 * 不提供這個參數不一樣平臺可能會有不一樣,因此,請顯式提供這個參數 */
declare function parseInt(s: string, radix?: number): number;
複製代碼
能夠看到 parseInt
其實有兩個參數,一個是必填的 s
,類型是 string
;
還有一個可選的 radix
,用來表示進制,例如填寫 10
的話,會把第一個參數解析成十進制,若是填寫 16
,會把傳進來的字符串解析成十六機制,原則上,這個參數最好都填寫。
返回值是一個整數。若是被解析參數的第一個字符沒法被轉化成數值類型,則返回 NaN
。面試
如下這堆都返回 15
數組
parseInt('0xF', 16);
parseInt('F', 16);
parseInt('17', 8);
parseInt(021, 8);
parseInt('015', 10); // parseInt(015, 10); 返回 15
parseInt(15.99, 10);
parseInt('15,123', 10);
parseInt('FXX123', 16);
parseInt('1111', 2);
parseInt('15 * 3', 10);
parseInt('15e2', 10);
parseInt('15px', 10);
parseInt('12', 13);
複製代碼
如下例子均返回 -15
函數
parseInt('-F', 16);
parseInt('-0F', 16);
parseInt('-0XF', 16);
parseInt(-15.1, 10);
parseInt(' -17', 8);
parseInt(' -15', 10);
parseInt('-1111', 2);
parseInt('-15e1', 10);
parseInt('-12', 13);
複製代碼
如下例子都返回 NaN
ui
parseInt('Hello', 8); // 根本就不是數值
parseInt('546', 2); // 除了「0、1」外,其它數字都不是有效二進制數字
parseInt('zz', 35); // z 是 35,在 35 進制裏面不可能有 35
複製代碼
返回 NaN
的例子改一下this
parseInt('Hello', 18); // 320, H = 17 e = 14 l = 21,能夠解析的 He 17 * 18 ^ 1 + 14 * 18 ^ 0 = 320
// H = 17 e = 14 l = 21,能夠解析的 Hell 17 * 22 ^ 3 + 14 * 22 ^ 2 + 21 * 22 ^ 1 + 21 * 22 ^ 0 = 188275
parseInt('Hello', 22); // 188275
parseInt('546', 10); // 546 這個不說了
parseInt('zz', 36); // 1295 z = 35,35 * 36 ^ 1 + 35 * 36 ^ 0 = 1295
複製代碼
傳入數字,如下例子都返回 4
,先 toString()
,而後小數點是無法解析的spa
parseInt(4.7, 10);
parseInt(4.7 * 1e22, 10); // 很是大的數值變成 4
parseInt(0.00000000000434, 10); // 很是小的數值變成 4
複製代碼
map
[1,2,3].map(parseInt)
// [1, NaN, NaN]
map<U>(callbackfn: (value: T, index: number, array: ReadonlyArray<T>) => U, thisArg?: any): U[]; 複製代碼
想必不少人都知道答案了,演算過程說一下大概就是,這裏還須要瞭解一些 map 的函數簽名,map 第一個參數是回調函數,有三個形參,雖然平時通常不會用到第三個,parseInt 接受的參數有兩個,因此實際運行起來的是這樣的code
[1, 2, 3].map((value, index) => parseInt(value, index));
複製代碼
三次演算過程分別是索引
parseInt(1, 0)
,按十進制處理,返回 1
parseInt(2, 1)
,基數不多是 1
,返回 NaN
parseInt(3, 2)
,二進制裏面不可能出現 3
的,返回 NaN
filter
find
findIndex
[1, 2, 3].filter(parseInt); //[1]
[1, 2, 3].find(parseInt); // 1
[1, 2, 3].findIndex(parseInt); // 0
複製代碼
filter
的回調函數簽名和 map
是同樣的,filter
的做用是,過濾掉返回值是假值的函數, find
是找到第一個返回值是真值的 item
,findIndex
的做用是,找到第一個返回是真值的 index
字符串
演算過程回調函數
parseInt(1, 0)
,按十進制處理,返回 1
,真值,find
返回 1
,findIndex
返回 0
,parseInt(2, 1)
,基數不多是 1
,返回 NaN
,假值,被過濾了parseInt(3, 2)
,二進制裏面不可能出現 3
的,返回 NaN
,假值,被過濾了這裏提一下, find
和 findIndex
是能夠用來作短路運算的,碰到 true
,就會退出,能夠用來替代 forEach
這種無法經過 return
退出的,可是這樣代碼語義化就很弱了。
reduce
[1,2,3].reduce(parseInt)
// 1
reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: ReadonlyArray<T>) => T, initialValue: T): T;
複製代碼
reduce
的回調參數有四個,一個是上一次循環返回的值,一個是當前值,一個是當前值索引,一個是原數組。這道題裏面沒有涉及到初始值,因此迭代是從 2
開始的。
兩次演算過程分別是:
parseInt(1, 2)
, 二進制 1
, 轉成十進制也是 1
,這時候,返回 1
,進入下一輪迭代parseInt(1, 3)
, 第二次迭代,上一次迭代的值是 1
,當前值是 3
, 三進制的 1
,返回 1
reduceRight
[1, 2, 3].reduceRight(parseInt);
// NaN
複製代碼
reduceRight
的簽名和 reduce
同樣,不過迭代是從右邊開始的。
兩次演算過程分別是:
parseInt(3, 2)
, 二進制 3
, 返回 NaN
parseInt(NaN, 1)
, 第二次迭代,上一次迭代的值是 NaN
,當前值是 1
, 基數爲 1
,返回 NaN
some
every
[1, 2, 3].some(parseInt); // true
[1, 2, 3].every(parseInt); // false
複製代碼
some
every
的回調函數簽名和 map
同樣,some
是有真值就返回 true, every
是所有都是真值才返回 true
。
演算過程分別是
parseInt(1, 0)
,按十進制處理,返回 1
,真值,some
返回 true
,運算結束parseInt(2, 1)
,基數不多是 1
,返回 NaN
,假值,every
返回 false
,運算結束這裏提一下, some
和 every
是能夠用來作短路運算的,some
碰到 true
,就會退出, every
碰到 false
就會退出,能夠用來替代 forEach
這種無法經過 return
退出的,可是這樣代碼語義化就很弱了。
forEach
[1, 2, 3].forEach(parseInt); // true
// undefined
複製代碼
這道題要是答錯了,是真的要給本身一巴掌。。。。
[1, 2, 3].map(parseInt);
有沒有通過類型轉換?有的。由於 parseInt
會把第一個傳進來的參數,若是不是 string
就要轉成 string
,這裏有個類型轉換
一個看似很簡單的 API
,其實考法還挺多的,若是不仔細瞭解的話,就不會知道其中的原理。