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接收的是两 ...
随机推荐
- hdu4148 Length of S(n)
Length of S(n) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)To ...
- centos/linux下的安装git
1.下载git wget https://github.com/git/git/archive/v2.14.1.zip 2.安装依赖 sudo yum -y install zlib-devel op ...
- MongoDB入门系列(四):权限管理
一.概述 本篇文章主要介绍如何创建用户和角色相关概念,同时对角色的添加和删除做了相关介绍. 版本:3.6.2 二.角色相关概念 1.数据库用户角色 read:该角色拥有数据的只读权限,系统集合以及sy ...
- Linux 格式化和挂载数据盘
如果您已经为 ECS 实例配了数据盘,您需要先格式化数据盘并挂载文件系统后才能正常使用数据盘. 注意: 磁盘分区和格式化是高风险行为,请慎重操作.本文档描述如何处理一个新买的数据盘,如果您的数据盘上有 ...
- Git (gnome-ssh-askpass:3871): Gtk-WARNING **: cannot open display:
在使用Git在客户端使用git push 命令提交文件到github时,出现报错 (gnome-ssh-askpass:): Gtk-WARNING **: cannot open display: ...
- Eclipse 安装 SVN 插件的两种方法
eclipse里安装SVN插件,一般来说,有两种方式: 直接下载SVN插件,将其解压到eclipse的对应目录里 使用eclipse 里Help菜单的“Install New Software”,通过 ...
- LOJ6001 - 「网络流 24 题」太空飞行计划
原题链接 Description 有个实验和个仪器,做实验有报酬买仪器有花费.每个实验都需要一些仪器,求最大净收益(实验报酬仪器花费),并输出一组方案. Solution 实验向所需仪器连边,实验的点 ...
- Redis--配置密码
可以通过以下方法进行密码的配置: ① 修改配置文件设置密码 ② 通过命令修改密码(重启redis后,新设置的密码会失效) 此处介绍第一种 1. 找到redis的配置文件,一般在/etc/redis.c ...
- 弄懂 JRE、JDK、JVM 之间的区别与联系
其实很多 Java 程序员在写了很多代码后,你问他 jre 和 jdk 之间有什么关系,jvm 又是什么东西,很多人不知所云.本篇不会讲述 jvm 底层是如何与不同的系统进行交互的,而主要理清楚三者之 ...
- R语言︱文本挖掘——词云wordcloud2包
每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 笔者看到微信公众号探数寻理中提到郎大为Chif ...