JavaScript之map与parseInt的陷阱
问题来源
这个问题的来源是学习廖雪峰老师JS教程。问题如下:小明希望利用map()
把字符串变成整数,他写的代码很简洁:
'use strict';
var arr = ['1', '2', '3'];
var r;
r = arr.map(parseInt);
console.log(r);
// [1, NaN, NaN]
为什么不是[1, 2, 3]?这是因为两个两个函数的定义有冲突。下面详解:
map的定义
注意到这个问题的原因是参考了这个国外某博客JavaScript可选参数危险。首先,我们了解一下map方法的定义,如下:
var new_array = arr.map(function callback(currentValue[, index[, array]]) {
// Return element for new_array
}[, thisArg])
其中参数有一个函数callback
,这个函数需要三个参数:currentValue
(必须):处理的数组中的当前元素;index
(可选):当前处理的元素在数组中的索引值;array
(可选):调用map的数组。thisArg
(可选):对象作为该执行回调时使用,传递给函数,用作 "this" 的值。
如果省略了 thisValue ,"this" 的值为 "undefined"。
所以,map函数接收的是两个参数,一个函数,另一个是thisArg
。这里我们主要关注的是其中的函数接收三个参数,一个必须,两个可选。问题就是出现在这里,函数接收三个参数。
parseInt的定义
这个函数用于解析一个字符串,并返回一个整数。定义如下:
parseInt(string, radix)
参数string
(必须):表示的是要被解析的字符串。radix
(可选):表示表示要解析的数字的基数。该值介于 2 ~ 36 之间。如果省略该参数或其值为 0,则数字将以 10 为基础来解析。如果它以 “0x” 或 “0X” 开头,将以 16 为基数。如果该参数小于 2 或者大于 36,则 parseInt() 将返回 NaN。第二个可选参数,就是问题的另一来源了。
问题详解
了解完两个函数的定义后,我们就知道小明代码的问题了:
var arr = ['1', '2', '3'];
var r;
r = arr.map(parseInt);
我们通常以为上述代码中 arr.map(parseInt);
表示的是
parseInt("1")
parseInt("2")
parseInt("3")
实际上应该是:
parseInt("1", 0, arr)
parseInt("2", 1, arr)
parseInt("3", 2, arr)
其中的arr
是['1', '2', '3']
。我们知道,JavaScript函数通常会忽略额外的参数,并且parseInt
只需要两个参数,因此我们不必担心theArray
这些调用中参数的影响。但是,第二个参数对parseInt
影响很大。parseInt("1", 0)
没有问题,0表示的是以二进制为基数解析‘1’
。但是后面的parseInt("2", 1)
以及parseInt("3", 2)
就有问题了。1
在parseInt
中是无效的基数,返回‘NaN’
值;2
虽然是有意义的基数,但是因为‘3’
不是合法的二进制数,所以也返回的是NaN
。至此,问题错误已经明了。下面是解决方案。
解决方案
解决的方法很简单,就是修饰一些parseInt
函数。代码如下:
'use strict';
var arr = ['1', '2', '3'];
var r;
r = arr.map(function parseInt2(x) {
return parseInt(x);
});
console.log(r);
或者我们使用Number()
方法,这样也会把字符串参数解析成十进制数,并且只需要一个参数。代码如下:
'use strict';
var arr = ['1', '2', '3'];
var r;
r = arr.map(Number);
console.log(r);
当然,也可以从map
下手解决问题。一个可能的方法如下:
Function.prototype.only = function(numberOfArgs) {
var self = this; //the original function
return function() {
return self.apply(this,[].slice.call(arguments,0,numberOfArgs))
}
};
arr.map(parseInt.only(1));
以上,就是JavaScript中map与parseInt冲突的问题的来源、解析、解决了。
JavaScript之map与parseInt的陷阱的更多相关文章
- JavaScript Array.map + parseInt
map 生成新数组的函数,3个参数 1-currentValue, callback数组中正在处理的当前元素 2-index(可选): callback数组中正在处理的当前元素的索引 3-array( ...
- 通过 ['1', '2', '3'].map(parseInt) 学习 map 和 parseInt 函数
看到一道笔试题: ['1', '2', '3'].map(parseInt) 这道题目中涉及到 map 和 parseInt 函数的运用,如果对这两个函数的理解不充分的话,是很难思考出正确的结果的. ...
- JavaScript之Map对象
前言 工欲善其事,必先利其器.这是一款以前在前端项目中没有使用过的.有趣的对象,咱来看看如何使用~ 并非arrayObj.map(function) //arrayObj.map与arrayObj.f ...
- javascript自定义Map对象
javascript定义map对象开发前端组件的重要性就不过多阐述了,直接参考以下案例即可 <script type=text/javascript charset=utf-8> func ...
- JavaScript的Map和Set
JavaScript的Map和Set 1.map:映射(通过key获得value).增.删 2.set:增.删.判断是否包含某个元素 1. Map <!DOCTYPE html><h ...
- JavaScript - map和parseInt的坑
问题: var arrs = ['1', '2', '3']; var r = arrs.map(parseInt); alert(r);//1,NaN,NaN map arr.map(functio ...
- JavaScript的面临的9个陷阱
虽然不是什么很高深的技术问题,但注意一下,会使您的编程轻松些,即所谓make life easier. 笔者对某些陷阱会混杂一些评点. 1. 最后一个逗号 如这段代码,注意最后一个逗号,按语言学角 ...
- 当map遇到parseInt
也是一道面试题,估计除了面试题,一般情况下,也不会写出类似的代码了. ['1', '2', '3'].map(parseInt) 这么一道题的返回结果是什么? 如果不用浏览器去验证,乍一看,似乎确实没 ...
- javaScript 的 map() reduce() foreach() filter()
map(映射), reduce(规约), forEach(遍历), filter(过滤),它们都是高阶函数,都是以传入不同的函数来以不同的方式操作数组元.ie都不支持 一.map方法 *概述 map( ...
随机推荐
- excel单元格内容合并
这几天在整理数据,有时候数据都在表格的不同单元格中,想把两格内容合并为一格,于是验证了两种方法 方法一: (1)在B1输入公式=A1&B1 (2)做完第一步后,选中B1后,鼠标移到单元格右下出 ...
- Vue源码学习之数据初始化
首发地址:CJWbiu's Blog 在这里思考一个问题,使用Vue的时候需要在创建Vue实例时传入一个option,这里包含了我们定义的props.methods.data等.而在methods的方 ...
- CUDA杂谈
这一年都在编写CUDA的程序,用了很多优化的手段,发现大部分其实还是官方的指南里面的手段 https://docs.nvidia.com/cuda/cuda-c-best-practices-guid ...
- Python编程实现USB转RS485串口通信
---作者吴疆,未经允许,严禁转载,违权必究--- ---欢迎指正,需要源码和文件可站内私信联系--- -----------点击此处链接至博客园原文----------- 功能说明:Python编程 ...
- android 开发-ListView与ScrollView事件冲突处理(事件分发机制处理)
ListView和ScrollView都存在滚动的效果,所以一般不建议listView和scrollView进行嵌套使用,但有些需求则需要用到两者嵌套.在android的学习中学了一种事件分发处理机制 ...
- hibernate log4j2输出sql带参数
网上有很多是输出sql ,参数以?的形式,后面输出参数binding的log,还要自己拼接特别麻烦:这里整理下输出原生sql的方法.组件是log4jdbc 1: 修改pom.xml,确定有下面的配置, ...
- 使用.NET配置文件appSettings元素的File属性
今天又一次郁闷了,看Orchard真实学到不少东西哇! Web.Config里面appSettings节点原来可以直接引用一个文件,以前还老想着微软真二,配置节点多了肿么办? 本质上来说,每一个可执行 ...
- 用python计算直角三角形斜边长
直接上代码 import math def hypotenuse(a,b): return(math.sqrt(a**2+b**2)) side1 = int(input("第一条直角边:& ...
- PHP中XML和数组互相转换的方法
转换代码如下 //数组转XML function arrayToXml($arr) { $xml = "<xml>"; foreach ($arr as $key=&g ...
- Masonry 等间隔或等宽高排列多个控件
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typica ...