最近碰到了[‘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 来判断数字的基数。

举例:

  1. 如果 string 以 "0x" 开头,parseInt() 会把 string 的其余部分解析为十六进制的整数。

  2. 如果 string 以 0 开头,那么 ECMAScript v3 允许 parseInt() 的一个实现把其后的字符解析为八进制或十六进制的数字。

  3. 如果 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 或 8
parseInt('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)问题解析的更多相关文章

  1. JavaScript Array.map + parseInt

    map 生成新数组的函数,3个参数 1-currentValue, callback数组中正在处理的当前元素 2-index(可选): callback数组中正在处理的当前元素的索引 3-array( ...

  2. JavaScript map+parseInt 容易产生的误区

    map /** * 语法: * var new_array = arr.map(function callback(currentValue[,index[,array]]){ * // return ...

  3. 通过 ['1', '2', '3'].map(parseInt) 学习 map 和 parseInt 函数

    看到一道笔试题: ['1', '2', '3'].map(parseInt) 这道题目中涉及到 map 和 parseInt 函数的运用,如果对这两个函数的理解不充分的话,是很难思考出正确的结果的. ...

  4. 解惑 ["1", "2", "3"].map(parseInt) 为何返回[1,NaN,NaN]

    javascript中的parseInt与map函数都是常用的函数,可是 ["1", "2", "3"].map(parseInt) 为何返 ...

  5. ["1", "2", "3"].map(parseInt) 为何返回[1,NaN,NaN]

    转载自:http://blog.csdn.net/freshlover/article/details/19034079 这涉及到是否深入理解两个函数的格式与参数含义. 首先根据我对两个函数用法的了解 ...

  6. 为什么 ["1", "2", "3"].map(parseInt) 返回 [1,NaN,NaN]?

    在 javascript 中 ["1","2","3"].map(parseInt) ,2,3] 却是 [1,NaN,NaN]? 我们首先回 ...

  7. ['1', '2', '3'].map(parseInt) what & why ?

    这是今天在 Advanced-Frontend组织 看到一个比较有意思的题目.主要是讲JS的映射与解析早在 2013年, 加里·伯恩哈德就在微博上发布了以下代码段: ['10','10','10',' ...

  8. 关于面试题:[1, 2, 3].map(parseInt)问题的剖析

    一.前言 最近有小伙伴在公号中咨询了胡哥这道面试题,窃以为是比较有意思的一道面试题,于此分享给各位小伙伴.先把答案给了各位,和你理解的一样吗?! [1, 2, 3].map(parseInt) // ...

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

    ["1", "2", "3"].map(parseInt)得到什么? 答案是:[1, NaN, NaN]. 原因:parseInt接收的是两 ...

随机推荐

  1. 打开word时出现the setup controller has encountered a problem during install解决办法

    问题电脑为win7,office是默认安装 删除下面文件夹即可解决该问题 C:\Program Files\Common Files\Microsoft Shared\OFFICE12\Office ...

  2. abp允许跨域代码,时间转换为固定格式,本地时间

     在Global的 Application_BeginRequest方法中: Thread.CurrentThread.CurrentCulture = new CultureInfo("z ...

  3. Effective Java 第三版——33. 优先考虑类型安全的异构容器

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  4. Mysql给某一台主机授权访问,修改root密码

    ubuntu上用的是phpstudy,安装好之后,敲mysql,提示没有,需要安装mysql的客户端. 安装好之后直接敲mysql,敲 mysql 再敲use mysql 再敲mysql -uroot ...

  5. Shell脚本的颜色样式及属性控制

    首先看一下格式 echo -e "\033[字背景颜色:文字颜色m字符串\033[0m" 举例 echo -e "\033[41;36m 字体 \033[0m" ...

  6. 关于Devexpress15.2中GridControl控件选择字段ColumnEdit下拉时间设置

    效果:点击表格GridControl控件中的列,可以显示日期和时间.时间可以手动修改.(绑定日期格式的字段) 设置步骤:1.点击时间字段列表设置ColumnEdit-New-选择DateEdit出现r ...

  7. 《android开发艺术探索》读书笔记(四)--View工作原理

    接上篇<android开发艺术探索>读书笔记(三) No1: View的三大流程:测量流程.布局流程.绘制流程 No2: ViewRoot对应于ViewRootImpl类,它是连接Wind ...

  8. hdu 1548 简单BFS

    题意:坐电梯,每次可以选着上下,对应移动的楼层是Ki,问从起点到终点最少要按几次. AC代码: #include<cstdio> #include<cstring> #incl ...

  9. EL表达式判断不能为空

    前几天在做一个网站的时候遇到一个问题,要判断一个在request或者session域里面的对象是否为空,利用EL表达式,正常思维就是用 <c:if test="${* != null} ...

  10. 使用SpringSecurity保护你的Eureka.

    因为注册中心基本上都是自己的应用在使用,应用不是特别多,可以写死,如果应用很多,那么就写入数据库把 pom <dependency> <groupId>org.springfr ...