為什么 ['1', '7', '11'].map(parseInt) 返回 [1, NaN, 3]

翻譯 alentan

原文 medium.com/dailyjs

批注 2019-07-12 104044.png

Javascript很奇怪锻梳。不相信我?嘗試使用map和parseInt將字符串?dāng)?shù)組轉(zhuǎn)換為整數(shù)挺举。啟動(dòng)控制臺(tái)(Chrome上的F12)创橄,粘貼以下內(nèi)容命斧,然后按Enter

['1', '7', '11'].map(parseInt);
復(fù)制代碼

我們最終得到的不是一個(gè)[1, 7, 11] 這樣的整數(shù)數(shù)組,而是這樣的長(zhǎng)這樣的 [1, NaN, 3] 一個(gè)數(shù)組。要了解到底發(fā)生了什么竭业,我們首先要討論一些 Javascript 概念智润。如果你想要一個(gè)摘要(TLDR),我在本故事結(jié)尾處加入了一個(gè)快速摘要未辆。

真值 & 假值

這是Javascript中一個(gè)簡(jiǎn)單的if-else語(yǔ)句:

if (true) {
    // 永遠(yuǎn)都會(huì)運(yùn)行
} else {
    // 永遠(yuǎn)不會(huì)運(yùn)行
}
復(fù)制代碼

在這種情況下窟绷,if-else 語(yǔ)句的條件為 true,因此始終執(zhí)行 if-block 語(yǔ)句塊并忽略 else-block 語(yǔ)句塊咐柜。這是一個(gè)簡(jiǎn)單的例子兼蜈,因?yàn)?true 是一個(gè)布爾值攘残。如果我們將非布爾值作為條件會(huì)怎么樣呢?

if ("hello world") {
    // 他會(huì)運(yùn)行嗎?
    console.log("Condition is truthy");
} else {
    // 還是運(yùn)行這個(gè)?
    console.log("Condition is falsy");
}
復(fù)制代碼

嘗試在瀏覽器的控制臺(tái)中運(yùn)行此代碼(Chrome上的F12)为狸。您應(yīng)該發(fā)現(xiàn) if-block 語(yǔ)句塊運(yùn)行歼郭。這是因?yàn)樽址畬?duì)象"hello world"是true。

每個(gè)Javascript對(duì)象當(dāng)放置在布爾上下文中時(shí)都是真值或假值辐棒。例如 if-else 語(yǔ)句病曾,會(huì)把Javascript對(duì)象轉(zhuǎn)為true或false。那么哪些對(duì)象是true的漾根,哪些是false的呢泰涂?這是一個(gè)簡(jiǎn)單的規(guī)則:

Javascript中當(dāng)以下的值放置在布爾上下文中時(shí)會(huì)返回false

false,0(""空字符串)辐怕,null负敏,undefined和NaN。

進(jìn)制(基數(shù))

0 1 2 3 4 5 6 7 8 9 10
復(fù)制代碼

當(dāng)我們從0到9計(jì)數(shù)時(shí)秘蛇,每個(gè)數(shù)字(0-9)都有不同的符號(hào)其做。但是,一旦我們達(dá)到10赁还,我們需要兩個(gè)不同的符號(hào)(1和0)來(lái)表示數(shù)字妖泄。這是因?yàn)槲覀兊男?shù)計(jì)數(shù)系統(tǒng)的基數(shù)(或進(jìn)制)為10。

基數(shù)是最小的數(shù)字艘策,只能由多個(gè)符號(hào)表示蹈胡。不同的計(jì)數(shù)系統(tǒng)具有不同的基數(shù),因此朋蔫,相同的數(shù)字可以指計(jì)數(shù)系統(tǒng)中的不同數(shù)字罚渐。

10進(jìn)制    二進(jìn)制    16進(jìn)制
0         0         0
1         1         1
2         10        2
3         11        3
4         100       4
5         101       5
6         110       6
7         111       7
8         1000      8
9         1001      9
10        1010      A
11        1011      B
12        1100      C
13        1101      D
14        1110      E
15        1111      F
16        10000     10
17        10001     11
復(fù)制代碼

例如,查看上表驯妄,我們看到相同的數(shù)字11可以表示不同計(jì)數(shù)系統(tǒng)中的不同數(shù)字荷并。如果進(jìn)制(基數(shù))為2,則表示數(shù)字 3青扔。如果進(jìn)制(基數(shù))為16源织,則表示數(shù)字17。

您可能已經(jīng)注意到微猖,在我們的示例中谈息,當(dāng)輸入為11時(shí),parseInt返回3凛剥,這對(duì)應(yīng)于上表中的二進(jìn)制列侠仇。

函數(shù)參數(shù)

Javascript中的函數(shù)可以使用任意數(shù)量的參數(shù)調(diào)用,即使它們不等于聲明的函數(shù)參數(shù)的數(shù)量犁珠。缺少的參數(shù)被視為未定義逻炊,而多余的參數(shù)會(huì)被忽略(但會(huì)存儲(chǔ)在類(lèi)似數(shù)組的參數(shù)對(duì)象中)互亮。

function foo(x, y) {
    console.log(x);
    console.log(y);
}
foo(1, 2);      // logs 1, 2
foo(1);         // logs 1, undefined
foo(1, 2, 3);   // logs 1, 2
復(fù)制代碼

map()函數(shù)

我們快到了!

Map是Array原型中的一個(gè)方法嗅骄,它返回一個(gè)新的數(shù)組胳挎,其結(jié)果是將原始數(shù)組的每個(gè)元素傳遞給一個(gè)函數(shù)。例如溺森,以下代碼將數(shù)組中的每個(gè)元素乘以3

function multiplyBy3(x) {
    return x * 3;
}
const result = [1, 2, 3, 4, 5].map(multiplyBy3);
console.log(result);   // logs [3, 6, 9, 12, 15];
復(fù)制代碼

現(xiàn)在慕爬,假設(shè)我想使用map()(沒(méi)有返回語(yǔ)句)記錄每個(gè)元素。我應(yīng)該能夠console.log作為一個(gè)參數(shù)傳遞給map()......

[1,2,3,4,5] .map(console.log);
復(fù)制代碼

[圖片上傳失敗...(image-4ee30b-1562899087851)]

<figcaption></figcaption>

一些非常奇怪的事情正在發(fā)生屏积。每次console.log調(diào)用都記錄索引和完整數(shù)組医窿,而不是僅記錄值。

[1, 2, 3, 4, 5].map(console.log);
// 上面的例子相當(dāng)于
[1, 2, 3, 4, 5].map(
    (val, index, array) => console.log(val, index, array)
);
// 而不是這樣
[1, 2, 3, 4, 5].map(
    val => console.log(val)
);
復(fù)制代碼

當(dāng)一個(gè)函數(shù)傳遞到map()炊林,對(duì)于每次迭代姥卢,三個(gè)參數(shù)傳遞到函數(shù):currentValue,currentIndex渣聚,和完整的array独榴。這就是每次迭代記錄三個(gè)條目的原因。

我們現(xiàn)在擁有解決這個(gè)謎團(tuán)所需的所有部分奕枝。

解開(kāi)謎團(tuán)

ParseInt有兩個(gè)參數(shù):string和radix(進(jìn)制)棺榔。如果提供的radix(進(jìn)制)為空或者為假值,進(jìn)制(基數(shù))默認(rèn)設(shè)置為10隘道。

parseInt('11');                => 11
parseInt('11', 2);             => 3
parseInt('11', 16);            => 17
parseInt('11', undefined);     => 11 (radix(進(jìn)制) 為假)
parseInt('11', 0);             => 11 (radix(進(jìn)制) 為假)
復(fù)制代碼

現(xiàn)在讓我們一步一步地運(yùn)行我們的示例症歇。

['1', '7', '11'].map(parseInt);       => [1, NaN, 3]
// 第一次迭代: val = '1', index = 0, array = ['1', '7', '11']
parseInt('1', 0, ['1', '7', '11']);   => 1
復(fù)制代碼

由于0是假的,因此進(jìn)制(基數(shù))設(shè)置為默認(rèn)值10谭梗。 parseInt()只接受兩個(gè)參數(shù)忘晤,因此['1', '7', '11']會(huì)被 忽略。字符串'1'在10進(jìn)制(基數(shù))中的字符串表示數(shù)字1激捏。

// 第二次迭代: val = '7', index = 1, array = ['1', '7', '11']
parseInt('7', 1, ['1', '7', '11']);   => NaN
復(fù)制代碼

在進(jìn)制(基數(shù))為1系統(tǒng)中设塔,符號(hào)'7'不存在。與第一次迭代一樣缩幸,忽略最后一個(gè)參數(shù)壹置。所以,parseInt()返回了NaN表谊。

// 第三次迭代: val = '11', index = 2, array = ['1', '7', '11']
parseInt('11', 2, ['1', '7', '11']);   => 3
復(fù)制代碼

在進(jìn)制(基數(shù))為2(二進(jìn)制)系統(tǒng)中,符號(hào)'11'表示數(shù)字3盖喷,最后一個(gè)參數(shù)被忽略爆办。

摘要(TLDR)

['1', '7', '11'].map(parseInt) 不能按預(yù)期工作,因?yàn)樵诿看蔚?map 傳遞三個(gè)參數(shù)到 parseInt()课梳。第二個(gè)參數(shù) index 作為radix(進(jìn)制)參數(shù)傳遞給 parseInt 距辆。因此余佃,使用不同的進(jìn)制(基數(shù))解析數(shù)組中的每個(gè)字符串。'7' 被解析為進(jìn)制(基數(shù))為 1跨算,它是 NaN爆土,'11' 被解析為進(jìn)制(基數(shù))為 2,它的值為 3诸蚕,'1' 被解析為默認(rèn)的進(jìn)制(基數(shù))為 10步势,因?yàn)樗乃饕?0 是假值。

作者:alentan
鏈接:https://juejin.im/post/5d0202da51882546dd10087b
來(lái)源:掘金
著作權(quán)歸作者所有背犯。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán)坏瘩,非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末漠魏,一起剝皮案震驚了整個(gè)濱河市倔矾,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌柱锹,老刑警劉巖哪自,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異禁熏,居然都是意外死亡壤巷,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)匹层,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)隙笆,“玉大人,你說(shuō)我怎么就攤上這事升筏〕湃幔” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵您访,是天一觀的道長(zhǎng)铅忿。 經(jīng)常有香客問(wèn)我,道長(zhǎng)灵汪,這世上最難降的妖魔是什么檀训? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮享言,結(jié)果婚禮上峻凫,老公的妹妹穿的比我還像新娘。我一直安慰自己览露,他們只是感情好荧琼,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布亭姥。 她就那樣靜靜地躺著含蓉,像睡著了一般景描。 火紅的嫁衣襯著肌膚如雪万哪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,554評(píng)論 1 305
  • 那天脐恩,我揣著相機(jī)與錄音镐侯,去河邊找鬼。 笑死驶冒,一個(gè)胖子當(dāng)著我的面吹牛苟翻,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播只怎,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼袜瞬,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了身堡?” 一聲冷哼從身側(cè)響起邓尤,我...
    開(kāi)封第一講書(shū)人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎贴谎,沒(méi)想到半個(gè)月后汞扎,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡擅这,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年澈魄,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片仲翎。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡痹扇,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出溯香,到底是詐尸還是另有隱情鲫构,我是刑警寧澤,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布玫坛,位于F島的核電站结笨,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏湿镀。R本人自食惡果不足惜炕吸,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望勉痴。 院中可真熱鬧赫模,春花似錦、人聲如沸蒸矛。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)莉钙。三九已至廓脆,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間磁玉,已是汗流浹背停忿。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蚊伞,地道東北人席赂。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像时迫,于是被迫代替她去往敵國(guó)和親颅停。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容