JavaScript Puzzlers 解密(一):為什么 ["1", "2", "3"].map(parseInt) 返回 [1, NaN, NaN]?

原文作者:justjavac

原文地址:http://justjavac.com/javascript/2014/02/18/javascript-puzzlers-why-1-2-3-map-parseint-returns-1-NaN-NaN-in-javascript.html

JavaScript Puzzlers!被稱為 javascript 界的專業(yè)八級測驗睛蛛,感興趣的 jser 可以去試試鳄抒。

我試了一下, 36 道題只做對了 19 道, 算下來正確率為 53%忽肛,還沒有及格。

第一題為["1", "2", "3"].map(parseInt)的返回值栈暇。

> ?["1", "2", "3"].map(parseInt)

? ? [1, NaN, NaN]

在javascript中["1", "2", "3"].map(parseInt)為何返回不是[1,2,3]卻是[1,NaN,NaN]麻裁?

我們首先回顧一下parseInt()個map()兩個函數(shù)的用法:

parseInt() 函數(shù)


定義和用法

parseInt()函數(shù)可解析一個字符串,并返回一個整數(shù)源祈。

語法

parseInt(string, radix)

參數(shù) ? ?    描述

string    必需煎源。要被解析的字符串。

radix     可選:表示要解析的數(shù)字的基數(shù)香缺。該值介于 2 ~ 36 之間手销。

如果省略該參數(shù)或其值為 `0`,則數(shù)字將以 10 為基礎(chǔ)來解析图张。如果它以 `"0x"` 或 `"0X"` 開頭锋拖,將以 16 為基數(shù)。

如果該參數(shù)小于 2 或者大于 36祸轮,則 `parseInt()` 將返回 `NaN`兽埃。

返回值

返回解析后的數(shù)字。

說明

當(dāng)參數(shù)radix的值為0适袜,或沒有設(shè)置該參數(shù)時柄错,parseInt()會根據(jù)string來判斷數(shù)字的基數(shù)。

舉例:

   1.如果string以"0x"開頭苦酱,parseInt()會把string的其余部分解析為十六進(jìn)制的整數(shù)售貌。

   2.如果string以0開頭,那么 ECMAScript v3 允許parseInt()的一個實現(xiàn)把其后的字符解析為八進(jìn)制或十六進(jìn)制的數(shù)字疫萤。

   3.如果string以 1 ~ 9 的數(shù)字開頭颂跨,parseInt()將把它解析為十進(jìn)制的整數(shù)。

提示和注釋

注釋:只有字符串中的第一個數(shù)字會被返回扯饶。

注釋:開頭和結(jié)尾的空格是允許的恒削。

提示:如果字符串的第一個字符不能被轉(zhuǎn)換為數(shù)字池颈,那么parseInt()會返回NaN。

實例

在本例中蔓同,我們將使用parseInt()來解析不同的字符串:

parseInt("10");// 返回 10 (默認(rèn)十進(jìn)制)

parseInt("19",10);// 返回 19 (十進(jìn)制: 10+9)

parseInt("11",2);// 返回 3 (二進(jìn)制: 2+1)

parseInt("17",8);// 返回 15 (八進(jìn)制: 8+7)

parseInt("1f",16);// 返回 31 (十六進(jìn)制: 16+15)

parseInt("010");// 未定:返回 10 或 8

map 方法


對數(shù)組的每個元素調(diào)用定義的回調(diào)函數(shù)并返回包含結(jié)果的數(shù)組饶辙。

array1.map(callbackfn[, thisArg])

參數(shù) ? ? ? ? ? ? ? ? ? ? ?定義

array1   ? ? ? ? ? ?必需蹲诀。一個數(shù)組對象斑粱。

callbackfn  ? ? ? ? ?必需。一個接受**最多**三個參數(shù)的函數(shù)脯爪。對于數(shù)組中的每個元素则北,`map` 方法都會調(diào)用 `callbackfn` 函數(shù)一次。

thisArg   ? ? ? ? ? 可選:可在 `callbackfn` 函數(shù)中為其引用 `this` 關(guān)鍵字的對象痕慢。如果省略 `thisArg`尚揣,則 `undefined` 將用作 `this` 值。

返回值

其中的每個元素均為關(guān)聯(lián)的原始數(shù)組元素的回調(diào)函數(shù)返回值的新數(shù)組掖举。

異常

如果callbackfn參數(shù)不是函數(shù)對象快骗,則將引發(fā)TypeError異常。

備注

對于數(shù)組中的每個元素塔次,map方法都會調(diào)用callbackfn函數(shù)一次(采用升序索引順序)方篮。 不為數(shù)組中缺少的元素調(diào)用該回調(diào)函數(shù)。

除了數(shù)組對象之外励负,map方法可由具有l(wèi)ength屬性且具有已按數(shù)字編制索引的屬性名的任何對象使用藕溅。

回調(diào)函數(shù)語法

回調(diào)函數(shù)的語法如下所示:

function callbackfn(value, index, array1)

可使用最多三個參數(shù)來聲明回調(diào)函數(shù)。

下表列出了回調(diào)函數(shù)參數(shù)继榆。

回調(diào)參數(shù)    ?定義

value      數(shù)組元素的值巾表。

index      數(shù)組元素的數(shù)字索引。

array1     ? 包含該元素的數(shù)組對象略吨。

修改數(shù)組對象

數(shù)組對象可由回調(diào)函數(shù)修改集币。

下表描述了在map方法啟動后修改數(shù)組對象所獲得的結(jié)果。

`map` 方法啟動后的條件         元素是否傳遞給回調(diào)函數(shù)

在數(shù)組的原始長度之外添加元素翠忠【瞎叮     否。

添加元素以填充數(shù)組中缺少的元素负间∨佳    是,如果該索引尚未傳遞給回調(diào)函數(shù)政溃。

元素被更改趾访。              是董虱,如果該元素尚未傳遞給回調(diào)函數(shù)扼鞋。

從數(shù)組中刪除元素申鱼。           否云头,除非該元素已傳遞給回調(diào)函數(shù)捐友。

示例

下面的示例闡釋了map方法的用法。

// 定義回調(diào)函數(shù)

// 計算圓的面積

function AreaOfCircle(radius){

  var area = Math.PI * (radius * radius);

  return area.toFixed(0);?

}

// 定義一個數(shù)組溃槐,保護(hù)三個元素

var radii = [10, 20, 30];

// 計算 radii 的面積.

var areas = radii.map(AreaOfCircle);

document.write(areas);// 輸出:

// 314,1257,2827

下面的示例闡釋thisArg參數(shù)的用法匣砖,該參數(shù)指定對其引用this關(guān)鍵字的對象。

// 定義一個對象 object昏滴,保護(hù) divisor 屬性和 remainder 方法

// remainder 函數(shù)求每個傳入的值的個位數(shù)猴鲫。(即除以 10 取余數(shù))

var obj = {? ?

?  divisor:10,? ?

?  remainder: function(value){

    returnvalue %this.divisor;? ??

  }?

}

// 定義一個包含 4 個元素的數(shù)組

var numbers = [6,12,25,30];

// 對 numbers 數(shù)組的每個元素調(diào)用 obj 對象的 remainder 函數(shù)。

// map 函數(shù)的第 2 個參數(shù)傳入 ogj谣殊。

var result = numbers.map(obj.remainder, obj);

document.write(result);

// 輸出:

// 6,2,5,0

在下面的示例中拂共,內(nèi)置 JavaScript 方法用作回調(diào)函數(shù)。

// 對數(shù)組中的每個元素調(diào)用 Math.sqrt(value) (求平方根)

var numbers = [9,16];

var result = numbers.map(Math.sqrt);

document.write(result);

// 輸出: 3,4

[9, 16].map(Math.sqrt)回調(diào)函數(shù)姻几,輸出的結(jié)果是[3, 4]宜狐。

但是為什么["1", "2", "3"].map(parseInt)卻返回[1,NaN,NaN]?

網(wǎng)站給出的提示是:

what you actually get is[1, NaN, NaN]becauseparseInttakes two parameters(val, radix)andmappasses 3(element, index, array)

簡單翻譯一下就是

parseInt需要 2 個參數(shù)(val, radix)蛇捌, 而map傳遞了 3 個參數(shù)(element, index, array)」抚恒。

通過上面的解釋,我們可以看出豁陆,如果想讓parseInt(string, radix)返回 NaN柑爸,有兩種情況:

  1.第一個參數(shù)不能轉(zhuǎn)換成數(shù)字。

  2.第二個參數(shù)不在 2 到 36 之間盒音。

我們傳入的參數(shù)都能轉(zhuǎn)換成數(shù)字表鳍,所以只能是第二種可能。

到底是不是呢祥诽?我們重新定義parseInt(string, radix)函數(shù):

var parseInt = function(string, radix){

  return string + "-" + radix;

};

["1", "2", "3"].map(parseInt);

輸出結(jié)果為:

["1-0", "2-1", "3-2"]

看見譬圣,map函數(shù)將數(shù)組的值value傳遞給了parseInt的第一個參數(shù),將數(shù)組的索引傳遞給了第二個參數(shù)雄坪。

第三個參數(shù)呢厘熟?我們再加一個參數(shù)

var parseInt = function(string, radix, obj){

  return string + "-" + radix +"-"+ obj;

};

["1", "2", "3"].map(parseInt);

輸出結(jié)果:

["1-0-1,2,3", "2-1-1,2,3", "3-2-1,2,3"]

我們再繼續(xù)增加參數(shù):

var parseInt = function(string, radix, obj, other){

  return string + "-" + radix +"-"+ obj +"-"+ other;

};

["1","2","3"].map(parseInt);

輸出結(jié)果:

["1-0-1,2,3-undefined", "2-1-1,2,3-undefined", "3-2-1,2,3-undefined"]

第四個參數(shù)為undefined,看見map確實為parseInt傳遞了三個參數(shù)维哈。就像作者寫道的:

(element, index, array)

  1.數(shù)組的值

  2.數(shù)組的索引

  3.數(shù)組

UPDATE 原文勘誤:(謝謝米粽粽提醒)

["1", "2", "3"].map(parseInt)

應(yīng)該對應(yīng)的是:

[parseInt("1", 0), ?parseInt("2", 1), ?parseInt("3", 2)]

parseInt("3", 2)的第二個參數(shù)是界于 2-36 之間的绳姨,之所以返回NaN是因為 字符串"3"里面沒有合法的二進(jìn)制數(shù),所以NaN阔挠。

我們還可以繼續(xù)試驗:

> ["1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1"].map(parseInt)

? ?[1,NaN,1,1,1,1,1,1,1,1,1,1,1,1,1,1]

只有當(dāng)?shù)诙€參數(shù)是1的時候返回NaN飘庄,其它情況都返回1。

> ["1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16"].map(parseInt) ? ? ? ?

? ?[1,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,9,11,13,15,17,19,21]

簡單列舉一下:

parseInt("1",0); // 十進(jìn)制 1

parseInt("2",1); // 第二個參數(shù)不在 2-36 直接

parseInt("3",2); // 二進(jìn)制 NaN

parseInt("4",3); // 三進(jìn)制

parseInt("5",4);

parseInt("6",5);

parseInt("7",6);

parseInt("8",7);

parseInt("9",8);

parseInt("10",9); // 九進(jìn)制 (1*9+0 = 9)

parseInt("11",10); // 十進(jìn)制 (1*10+1 = 11)

parseInt("12",11);

parseInt("13",12);

parseInt("14",13);

parseInt("15",14);

parseInt("16",15);

(全文完)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末购撼,一起剝皮案震驚了整個濱河市跪削,隨后出現(xiàn)的幾起案子谴仙,更是在濱河造成了極大的恐慌,老刑警劉巖碾盐,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件晃跺,死亡現(xiàn)場離奇詭異,居然都是意外死亡毫玖,警方通過查閱死者的電腦和手機(jī)掀虎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來孕豹,“玉大人涩盾,你說我怎么就攤上這事十气±常” “怎么了?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵砸西,是天一觀的道長叶眉。 經(jīng)常有香客問我,道長芹枷,這世上最難降的妖魔是什么衅疙? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮鸳慈,結(jié)果婚禮上饱溢,老公的妹妹穿的比我還像新娘。我一直安慰自己走芋,他們只是感情好绩郎,可當(dāng)我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著翁逞,像睡著了一般肋杖。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上挖函,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天状植,我揣著相機(jī)與錄音,去河邊找鬼怨喘。 笑死津畸,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的必怜。 我是一名探鬼主播肉拓,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼棚赔!你這毒婦竟也來了帝簇?” 一聲冷哼從身側(cè)響起徘郭,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎丧肴,沒想到半個月后残揉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡芋浮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年抱环,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片纸巷。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡镇草,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出瘤旨,到底是詐尸還是另有隱情梯啤,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布存哲,位于F島的核電站因宇,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏祟偷。R本人自食惡果不足惜察滑,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望修肠。 院中可真熱鬧贺辰,春花似錦、人聲如沸嵌施。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽艰管。三九已至滓侍,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間牲芋,已是汗流浹背撩笆。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留缸浦,地道東北人夕冲。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像裂逐,于是被迫代替她去往敵國和親歹鱼。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,786評論 2 345

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