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

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

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

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

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

parseInt()

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

var n = parseInt('123')

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

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

var m = parseInt('xyz)

此时m的值应该就是NaN。

Array.prototype.map

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

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

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

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

解决方法

现在来看看ECMAScript 5 中parseInt 的用法。有会发现它可以接受两个参数。第一个参数是要被解析的字符串,第二个参数是要解析成数值的基础。所以,
parseInt('ffff',16)
返回的结果是65535,然而

parseInt('ffff',8)

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

parseInt("12",10) ;
parseInt("12") ;
parseInt("12",0) ;

都会返回数值12。

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

parseInt('1')
parseInt('2')
parseInt('3')

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

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中有三个参数。所以这里结合起来,就导致了上面问题。
换个方式写:

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

这样就不会出错。

当然,我们也可以写:

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









参考:http://www.wirfs-brock.com/allen/posts/166

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值