您的位置:首页 > Web前端 > JavaScript

JavaScript:['1','2','3'].map(parseInt)问题解析

2015-12-11 11:18 876 查看
最近碰到了[‘1’,’2’,’3’].map(parseInt)这种看似不起眼陷阱却极大的问题。

这乍一看,感觉应该会输出[1,2,3]。但是,实际上并不是我们想的这样。你可以现在打开console,看看输出的结果。

出乎意料结果竟然是[1,NaN,NaN].

至于为什么是这样,下面一步一步的解释。

parseInt()

parseInt是JS的一个内置函数,它可以将字符创解析成一个数值表达式并将该数值返回。调用的时候如下:

[code]var n = parseInt('123')


函数返回的结果是123 ,并赋值给变量n。这里应该没什么问题。

当然,如果传入pasreInt()参数并不能被解析成数值表达式,那么函数执行后将返回 NaN。NaN的含义就是Not a Number(不是一个数值)。

[code]var m = parseInt('xyz)


此时m的值应该就是NaN。

Array.prototype.map

map 是ECMAScript 5 的一个内置数值方法.map把函数作为它的参数。map遍历数组中所有的元素,并且为每个元素调用一次这个传入map中的函数,当前元素作为参数传入该函数。map函数调用完毕之后将返回的结果存入一个新数组中。看下面这个例子:

[code][1,2,3].map(function(value){
        return value+1
    })


很好理解,最后的结果的应该是[2,3,4].这种调用应该是很常见的。但是有时将已经存在的函数作为参数传入map是无效的啊,比如parseInt.

清楚了parsenInt和map的基本用法之后,再来看看比较容易忽视的问题。

解决方法

现在来看看ECMAScript 5 中parseInt 的用法。有会发现它可以接受两个参数。第一个参数是要被解析的字符串,第二个参数是要解析成数值的基础。所以,

parseInt('ffff',16)


返回的结果是65535,然而

[code]parseInt('ffff',8)


返回的结果是NaN,因为“ffff”并不能解析成一个八进制的数值。如果第二个参数省略了或者是0,parseInt默认为是10进制 所以

[code]parseInt("12",10) ;
parseInt("12") ;
parseInt("12",0) ;


都会返回数值12。

现在看看map

的定义。map指定传入的函数参数作为callbackfn.规范里指出:“callbackfn调用时需要传入三个参数:元素的值,元素的索引和正在被遍历的对象”。仔细体会一下,原本我们以为对parseInt的三次调用是这样:

[code]parseInt('1')
parseInt('2')
parseInt('3')


然而实际上是这样调用的:

[code]parseInt('1',0,theArray);
parseInt('2',1,theArray);
parseInt('3',2,theArray);


这里theArray 就是原始数组[‘1’,’2’,’3’]。

JS函数一般会自动忽视多余的参数,parseInt仅仅需要两个参数,所以我们并不需要担心这个theArray参数对parseInt的影响。

重点来了,第二个参数是如何影响parseInt的

在第一次调用时,parseInt的第二个参数是0,上面已经说了,所以第一调用

parseInt('1',0)


返回1.

第二次调用第二个参数是1,也是说1作为数值的基础。规范里说的很清楚了,如果基础是非0或者小于2,函数都不会查询字符串直接返回NaN。

第三次调用时,2作为基数。这就意味着字符串将被解析成字节数,也就是仅仅包含数值0和1。parseInt的规范第十一步指出,它仅尝试分析第一个字符的左侧,这个字符还不是要求基数的有效数字。这个字符串的第一个字符是“3”,它并不是基础基数2的一个有效数字。所以这个子字符串将被解析为空。第十二步说了:如果子字符串被解析成空了,函数将返回为NaN。

所以这里的结果就应该是[1,NaN,NaN].

这里问题所在就是容易忽视parseInt是需要两个参数的。map中有三个参数。所以这里结合起来,就导致了上面问题。

换个方式写:

[code]['1','2','3'].map(function(value){
        return parseInt(value)
})


这样就不会出错。

当然,我们也可以写:

[code]['1','2','3'].map(Number)




参考:http://www.wirfs-brock.com/allen/posts/166
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: