看到一道筆試題:
['1', '2', '3'].map(parseInt)
這道題目中涉及到 map 和 parseInt 函數的運用,如果對這兩個函數的理解不充分的話,是很難思考出正確的結果的。
下面就通過這道題目對 map 和 parseInt 函數作一個簡單的理解和分析:
map((item, index, thisArr) => ( newArr ))
【參數解析】
item: callback 的第一個參數,數組中正在處理的當前元素。
index: callback 的第二個參數,數組中正在處理的當前元素的索引。
thisArr: callback 的第三個參數,map 方法被調用的數組。
【返回】
一個新數組,每個元素都是執行回調函數的結果。
parseInt(string, radix)
【參數解析】
string: 必需。要被解析的字符串。
radix: 可選。表示要解析的字符串的基數。該值介於 2 ~ 36 之間。如果省略該參數或其值為 0,則數字將以 10 為基礎來解析。如果它以 “0x” 或 “0X” 開頭,將以 16 為基數。如果該參數小於 2 或者大於 36,則 parseInt() 將返回 NaN。
【返回】
解析后的數字
【注意】
1. 只有字符串中的第一個數字會被返回。 // parseInt(' 12abc!6') 12 2. 開頭和結尾的空格是允許的。 // parseInt(' 12x') 12 3. 如果字符串的第一個字符不能被轉換為數字,那么 parseInt() 會返回 NaN。 // parseInt('s90') NaN 4. radix 表示的是當前要解析的字符串的表示進制數,而不是解析的進制數。 // parseInt('3', 2) 表示當前的字符串'3' 是以二進制表示的(當然這是不合規則的,僅為說明問題),而不是將 3 用二進制作轉換
【示例】
parseInt("10"); // 10 parseInt("19",10); // 19 (10+9) parseInt("11",2); // 3 (2+1) parseInt("17",8); // 15 (8+7) parseInt("1f",16); // 31 (16+15) parseInt("010"); // 10 或 8
['1', '2', '3'].map(parseInt) 解析
通過上述對 map 和 parseInt 函數的分析可以知道,執行方法時,map給parseInt傳遞了三個參數:
parseInt(item, index, thisArr)
其中第三個參數會被 parseInt 忽略,因此會依次執行:
parseInt('1', 0) // radix 為 0,默認以十進制解析字符串,返回 1 parseInt('2', 1) // radix 為 1,不在 2 ~ 36 之間,返回 NaN parseInt('3', 2) // radix 為 2, 字符串卻為 3,超出二進制的表示范圍,因此要解析的字符串和基數矛盾,返回 NaN
綜上,最后返回的數組為 [1, NaN, NaN]
【補充】
一些看起來奇怪但實際上解釋得通的例子:
parseInt(false, 16) // 250 parseInt(parseInt, 16) // 15 parseInt('0x10', 16) // 16 parseInt('103', 2) // 2 parseInt(1/0, 19) // 18
【參考】
為什么 ["1", "2", "3"].map(parseInt) 返回 [1,NaN,NaN]?
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/map
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/parseInt