parseInt 陷阱
從一道面試題說起
前端圈內流傳着一道非常經典,但是非常容易踩坑的面試題。如下:
["1", "2", "3"].map(parseInt)
// A. ["1", "2", "3"]
// B. [1, 2, 3]
// C. [0, 1, 2]
// D. other
請問,你認爲表達式的返回值會是神馬?
相信大多數人的第一反應便是應該選 B。
但正如你所料,選 B 是不對的。
答案是 D。
真正的產出是: [1, NaN, NaN]
["1", "2", "3"].map(parseInt)
// [1, NaN, NaN]
到這裏,許多人都會問出心中不解的疑惑:爲什麼呢?
map 方法
Array.prototype.map 函數是大家常用的一個方法,具體用法在本文就不詳細展開了,有興趣的可以參考mdn 文檔
map() 方法創建一個新數組,其結果是該數組中的每個元素都調用一個提供的函數後返回的結果。
在本題中需要注意的是,它提供給函數的不是 1 個入參,而是 3 個。
["1", "2", "3"].map((item, index, arr) => {...})
這一點至關重用。
item: 也就是數組中的"1", "2", "3"
index: 當前遍歷數組的下標,0, 1, 2
arr: 數組的引用"1", "2", "3"
parseInt 方法
parseInt 也是大家編程過程中常用的方法,常見於將字符串、浮點數轉換成整型的數。
parseInt("1") // 1
parseInt(1.3) // 1
但實際上,該方法的入參是有兩個的。
讓我們看看 mdn 上的文檔。[文檔地址](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/parseInt)
parseInt(string, radix) string 爲字符串,radix 爲介於 2-36 之間的數。使用者告訴這個函數 string(比如 11)是 radix(比如 2)進制的,函數將固定返回 string 以十進制時顯示的數(3)
以下是例子:
parseInt(10, 0) // 10,因爲不存在0進制,因此仍然會作爲默認值10進制處理
parseInt(10, 1) // NaN, 10 超出了1進制的範疇,所以此處返回NaN
parseInt(10, 2) // 2衆所周知,在2進制中,10是2
parseInt(10, 3) // 3
……
知道了這一點,結合 map 方法的用法,我們便可以快速整理出本題的解題思路,答案如下:
[parseInt("1", 0), parseInt("2", 1), parseInt("3", 2)]
parseInt("1", 0) // 1, 因爲不存在0進制,因此仍然會作爲默認值10進制處理
parseInt("2", 1) // NaN, 2超出了1進制的範疇
parseInt("3", 2) // NaN, 3超出了2進制的範疇
parseInt 方法的一些拓展和細節
以下例子均返回 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);
以下例子均返回 NaN:
parseInt("Hello", 8); // 根本就不是數值
parseInt("546", 2); // 除了“0、1”外,其它數字都不是有效二進制數字
以下例子均返回 -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);
下例中全部返回 4:
parseInt(4.7, 10);
parseInt(4.7 * 1e22, 10); // 非常大的數值變成 4
parseInt(0.00000000000434, 10); // 非常小的數值變成 4
下面的例子返回 224:
parseInt("0e0",16);
總結
關於 parseInt 的陷阱,本期就介紹到這裏。
歡迎訪問我的 github,並給我一顆愛的小星星~
github地址