本文轉(zhuǎn)自 https://github.com/sisterAn/blog/issues/19
這是今天在 Advanced-Frontend組織 看到一個比較有意思的題目。
主要是講JS的映射與解析
早在 2013年, 加里·伯恩哈德就在微博上發(fā)布了以下代碼段:
['10','10','10','10','10'].map(parseInt);
// [10, NaN, 2, 3, 4]
parseInt
parseInt() 函數(shù)解析一個字符串參數(shù),并返回一個指定基數(shù)的整數(shù) (數(shù)學系統(tǒng)的基礎(chǔ))。
const intValue = parseInt(string[, radix]);
string 要被解析的值。如果參數(shù)不是一個字符串,則將其轉(zhuǎn)換為字符串(使用 ToString 抽象操作)。字符串開頭的空白符將會被忽略。
radix 一個介于2和36之間的整數(shù)(數(shù)學系統(tǒng)的基礎(chǔ)),表示上述字符串的基數(shù)。默認為10。
返回值 返回一個整數(shù)或NaN
parseInt(100); // 100
parseInt(100, 10); // 100
parseInt(100, 2); // 4 -> converts 100 in base 2 to base 10
注意:
在radix為 undefined,或者radix為 0 或者沒有指定的情況下,JavaScript 作如下處理:
- 如果字符串 string 以"0x"或者"0X"開頭, 則基數(shù)是16 (16進制).
- 如果字符串 string 以"0"開頭, 基數(shù)是8(八進制)或者10(十進制),那么具體是哪個基數(shù)由實現(xiàn)環(huán)境決定。ECMAScript 5 規(guī)定使用10,但是并不是所有的瀏覽器都遵循這個規(guī)定。因此,永遠都要明確給出radix參數(shù)的值。
- 如果字符串 string 以其它任何值開頭,則基數(shù)是10 (十進制)。
更多詳見parseInt | MDN
map
map() 方法創(chuàng)建一個新數(shù)組,其結(jié)果是該數(shù)組中的每個元素都調(diào)用一個提供的函數(shù)后返回的結(jié)果。
var new_array = arr.map(function callback(currentValue[,index[, array]]) {
// Return element for new_array
}[, thisArg])
可以看到callback回調(diào)函數(shù)需要三個參數(shù), 我們通常只使用第一個參數(shù) (其他兩個參數(shù)是可選的)。
currentValue 是callback 數(shù)組中正在處理的當前元素。
index可選, 是callback 數(shù)組中正在處理的當前元素的索引。
array可選, 是callback map 方法被調(diào)用的數(shù)組。
另外還有thisArg可選, 執(zhí)行 callback 函數(shù)時使用的this 值。
const arr = [1, 2, 3];
arr.map((num) => num + 1); // [2, 3, 4]
更多詳見Array.prototype.map() | MDN
回到真實的事例上
回到我們真實的事例上
['1', '2', '3'].map(parseInt)
對于每個迭代map, parseInt()傳遞兩個參數(shù): 字符串和基數(shù)。
所以實際執(zhí)行的的代碼是:
['1', '2', '3'].map((item, index) => {
return parseInt(item, index)
})
即返回的值分別為:
parseInt('1', 0) // 1
parseInt('2', 1) // NaN
parseInt('3', 2) // NaN, 3 不是二進制
所以:
['1', '2', '3'].map(parseInt)
// 1, NaN, NaN
由此,加里·伯恩哈德例子也就很好解釋了,這里不再贅述
['10','10','10','10','10'].map(parseInt);
// [10, NaN, 2, 3, 4]
如何在現(xiàn)實世界中做到這一點
如果您實際上想要循環(huán)訪問字符串數(shù)組, 該怎么辦? map()然后把它換成數(shù)字?使用編號!
['10','10','10','10','10'].map(Number);
// [10, 10, 10, 10, 10]