问题来源

​ 这个问题的来源是学习廖雪峰老师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)就有问题了。1parseInt中是无效的基数,返回‘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的陷阱的更多相关文章

  1. JavaScript Array.map + parseInt

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

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

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

  3. JavaScript之Map对象

    前言 工欲善其事,必先利其器.这是一款以前在前端项目中没有使用过的.有趣的对象,咱来看看如何使用~ 并非arrayObj.map(function) //arrayObj.map与arrayObj.f ...

  4. javascript自定义Map对象

    javascript定义map对象开发前端组件的重要性就不过多阐述了,直接参考以下案例即可 <script type=text/javascript charset=utf-8> func ...

  5. JavaScript的Map和Set

    JavaScript的Map和Set 1.map:映射(通过key获得value).增.删 2.set:增.删.判断是否包含某个元素 1. Map <!DOCTYPE html><h ...

  6. JavaScript - map和parseInt的坑

    问题: var arrs = ['1', '2', '3']; var r = arrs.map(parseInt); alert(r);//1,NaN,NaN map arr.map(functio ...

  7. JavaScript的面临的9个陷阱

    虽然不是什么很高深的技术问题,但注意一下,会使您的编程轻松些,即所谓make life easier. 笔者对某些陷阱会混杂一些评点. 1.   最后一个逗号 如这段代码,注意最后一个逗号,按语言学角 ...

  8. 当map遇到parseInt

    也是一道面试题,估计除了面试题,一般情况下,也不会写出类似的代码了. ['1', '2', '3'].map(parseInt) 这么一道题的返回结果是什么? 如果不用浏览器去验证,乍一看,似乎确实没 ...

  9. javaScript 的 map() reduce() foreach() filter()

    map(映射), reduce(规约), forEach(遍历), filter(过滤),它们都是高阶函数,都是以传入不同的函数来以不同的方式操作数组元.ie都不支持 一.map方法 *概述 map( ...

随机推荐

  1. 007 Reverse Integer 旋转整数

    Given a 32-bit signed integer, reverse digits of an integer.Example 1:Input: 123Output:  321Example ...

  2. (转)centos7优化内核参数详解

    centos7优化内核参数详解 原文:http://blog.csdn.net/xiegh2014/article/details/52132863 cat /etc/sysctl.conf #CTC ...

  3. 迷你迅雷+SqlServer2008r2下载

    迷你迅雷下载 http://down.sandai.net/mini/MiniThunderInstaller3.1.1.58.exe SqlServer 2008r2下载 ed2k://|file| ...

  4. 牛客网Java刷题知识点之匿名对象

    不多说,直接上干货! 匿名对象的两种用途: 1.当对象对方法仅进行一次调用的时候,就可以简化成匿名对象. 2.匿名对象可以作为实际参数进行传递. 匿名对象顾名思义就是没有名字的对象. new Car( ...

  5. Sqoop概述

    sqoop Sqoop 是传统数据库与 Hadoop 之间数据同步的工具,它是 Hadoop 发展到一定程度的必然产物,它主要解决的是传统数据库和Hadoop之间数据的迁移问题.这节课我们将详细介绍 ...

  6. 基于C#编程语言的Mysql常用操作

    一.开始需要先将C#中与mysql相关的引用添加进来 using MySql.Data.MySqlClient; 二.创建一个database MySqlConnection m_conn = new ...

  7. pat1099. Build A Binary Search Tree (30)

    1099. Build A Binary Search Tree (30) 时间限制 100 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN ...

  8. json java simple-json

    http://code.google.com/p/json-simple/wiki/EncodingExamples#Example_1-1_-_Encode_a_JSON_object javac ...

  9. 最简实例演示asp.net5中用户认证和授权(2)

    上接最简实例演示asp.net5中用户认证和授权(1) 基础类建立好后,下一步就要创建对基础类进行操作的类了,也就是实现基础类的增删改查(听起来不太高大上),当然,为了使用asp.net5的认证机制, ...

  10. oracle中查找与已知表的数据库对象

    在此次情况中,业务顾问就给我提供了一张客户公司客户化的Form,然后让找出界面上的数据是怎样生成的. 首先我们从EBS form 界面上找到了界面的数据来源于一张表ks_so_line_margin_ ...