JavaScript:['1','2','3'].map(parseInt)问题解析
最近碰到了[‘1’,’2’,’3’].map(parseInt)这种看似不起眼陷阱却极大的问题。
这乍一看,感觉应该会输出[1,2,3]。但是,实际上并不是我们想的这样。你可以现在打开console,看看输出的结果。
出乎意料结果竟然是[1,NaN,NaN].
至于为什么是这样,下面一步一步的解释。
parseInt() 函数
定义和用法
parseInt()
函数可解析一个字符串,并返回一个整数。
语法
parseInt(string, radix)
参数 | 描述 |
---|---|
string | 必需。要被解析的字符串。 |
radix |
可选。表示要解析的数字的基数。该值介于 2 ~ 36 之间。 如果省略该参数或其值为 ‘0‘,则数字将以 10 为基础来解析。如果它以 ‘”0x”‘ 或 ‘”0X”‘ 开头,将以 16 为基数。 如果该参数小于 2 或者大于 36,则 ‘parseInt()‘ 将返回 ‘NaN‘。 |
返回值
返回解析后的数字。
说明
当参数 radix
的值为 0
,或没有设置该参数时,parseInt()
会根据 string
来判断数字的基数。
举例:
如果
string
以"0x"
开头,parseInt()
会把string
的其余部分解析为十六进制的整数。如果
string
以0
开头,那么 ECMAScript v3 允许parseInt()
的一个实现把其后的字符解析为八进制或十六进制的数字。如果
string
以 1 ~ 9 的数字开头,parseInt()
将把它解析为十进制的整数。
提示和注释
注释:只有字符串中的第一个数字会被返回。
注释:开头和结尾的空格是允许的。
提示:如果字符串的第一个字符不能被转换为数字,那么 parseInt()
会返回 NaN
。
实例
在本例中,我们将使用 parseInt()
来解析不同的字符串:
parseInt("10"); // 返回 10 (默认十进制)
parseInt("19",10); // 返回 19 (十进制: 10+9)
parseInt("11",2); // 返回 3 (二进制: 2+1)
parseInt("17",8); // 返回 15 (八进制: 8+7)
parseInt("1f",16); // 返回 31 (十六进制: 16+15)
parseInt("010"); // 未定:返回 10 或 8parseInt('123'); //123
当然,如果传入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)
JavaScript:['1','2','3'].map(parseInt)问题解析的更多相关文章
- JavaScript Array.map + parseInt
map 生成新数组的函数,3个参数 1-currentValue, callback数组中正在处理的当前元素 2-index(可选): callback数组中正在处理的当前元素的索引 3-array( ...
- JavaScript map+parseInt 容易产生的误区
map /** * 语法: * var new_array = arr.map(function callback(currentValue[,index[,array]]){ * // return ...
- 通过 ['1', '2', '3'].map(parseInt) 学习 map 和 parseInt 函数
看到一道笔试题: ['1', '2', '3'].map(parseInt) 这道题目中涉及到 map 和 parseInt 函数的运用,如果对这两个函数的理解不充分的话,是很难思考出正确的结果的. ...
- 解惑 ["1", "2", "3"].map(parseInt) 为何返回[1,NaN,NaN]
javascript中的parseInt与map函数都是常用的函数,可是 ["1", "2", "3"].map(parseInt) 为何返 ...
- ["1", "2", "3"].map(parseInt) 为何返回[1,NaN,NaN]
转载自:http://blog.csdn.net/freshlover/article/details/19034079 这涉及到是否深入理解两个函数的格式与参数含义. 首先根据我对两个函数用法的了解 ...
- 为什么 ["1", "2", "3"].map(parseInt) 返回 [1,NaN,NaN]?
在 javascript 中 ["1","2","3"].map(parseInt) ,2,3] 却是 [1,NaN,NaN]? 我们首先回 ...
- ['1', '2', '3'].map(parseInt) what & why ?
这是今天在 Advanced-Frontend组织 看到一个比较有意思的题目.主要是讲JS的映射与解析早在 2013年, 加里·伯恩哈德就在微博上发布了以下代码段: ['10','10','10',' ...
- 关于面试题:[1, 2, 3].map(parseInt)问题的剖析
一.前言 最近有小伙伴在公号中咨询了胡哥这道面试题,窃以为是比较有意思的一道面试题,于此分享给各位小伙伴.先把答案给了各位,和你理解的一样吗?! [1, 2, 3].map(parseInt) // ...
- ["1", "2", "3"].map(parseInt)?
["1", "2", "3"].map(parseInt)得到什么? 答案是:[1, NaN, NaN]. 原因:parseInt接收的是两 ...
随机推荐
- jQuery(function(){...})与(function($){...})(jQuery)的“兄弟”情结
记得那时在学习写基于jQuery的插件时,了解到(function($){...})(jQuery)的代码结构,一开始还没发觉,后来百度了解它的语意时,从搜索结果中发现了jQuery(function ...
- 利用fiddler和mock调试本地微信网页
利用fiddler和mock调试本地微信网页 微信公众号网页是比较特殊的页面,普通页面直接打开即可访问,但对于需要请求微信相关接口的部分需要安全域名认证.这导致了使用mock数据进行开发的页面没办法走 ...
- java中错误日志的用法
1.maven包:将下面的maven加入到pom.xml <!-- https://mvnrepository.com/artifact/log4j/log4j --><depend ...
- 修改maven项目jdk版本,并解决Dynamic Web Module 3.1 requires Java 1.7 or newer错误
使用maven的时候,默认会使用1.5版本的JDK,并且创建项目时也会是1.5版本. 但是我想用JDK1.7版本,所以我手动将maven项目JDK改为1.7版本. 手动修改JDK版本为1.7以后,项目 ...
- java网络编程(4)——udp实现聊天
UDP可以实现在线聊天功能,我这里就是简单模拟一下: 发送端: package com.seven.udp; import java.io.BufferedReader; import java.io ...
- day4(while 、练习题)
一.while ... else 方法 while else 的作用就是,确定循环正确执行完毕,else里面可以提示完成的情况. 二.练习题 1.编译型语言是编译完之后执行,解释性语言是边编译边执行, ...
- SIFT解析(三)生成特征描述子
以上两篇文章中检测在DOG空间中稳定的特征点,lowe已经提到这些特征点是比Harris角点等特征还要稳定的特征.下一步骤我们要考虑的就是如何去很好地描述这些DOG特征点. 下面好好说说如何来描述这些 ...
- Java 多线程入门
进程与线程 在学习Java多线程之前,先简单复习一下进程与线程的知识. 进程:进程是系统进行资源分配和调度的基本单位,可以将进程理解为一个正在执行的程序,比如一款游戏. 线程:线程是程序执行的最小单位 ...
- ORACLE不可见索引(Invisible Indexes)
不可见索引概念 不可见索引(Invisible Index)是ORACLE 11g引入的新特性.不可见索引是会被优化器忽略的不可见索引,除非在会话或系统级别上将OPTIMIZER_USE_INVISI ...
- 1.2 PCI总线的信号定义
PCI总线是一条共享总线,在一条PCI总线上可以挂接多个PCI设备.这些PCI设备通过一系列信号与PCI总线相连,这些信号由地址/数据信号.控制信号.仲裁信号.中断信号等多种信号组成. PCI总线是一 ...