前端面試寶典之:parseInt的陷阱

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地址

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章