解惑 [1, 2, 3].map(parseInt) 为何返回[1,NaN,NaN]
javascript中的parseInt与map函数都是常用的函数,可是 ["1", "2", "3"].map(parseInt) 为何返回不是[1,2,3]却是[1,NaN,NaN]?
这涉及到是否深入理解两个函数的格式与参数含义。
首先根据我对两个函数用法的了解,猜测是由于parseInt(string, radix) 的参数radix必须介于2~36之间,而且字符串string中的数字不能大于radix才能正确返回数字结果值。
我们通过以下javascript代码测试一下:
- var a=["1", "2", "3", "4","5",6,7,8,9,10,11,12,13,14,15];
- a.map(parseInt);
返回结果为:[1,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,9,11,13,15,17,19]
正好印证了以上的猜测是正确的,因为:
parseInt('1',0) = 1,
parseInt('2',1) = NaN,
parseInt('3',2) = NaN,
……
正是由于map的回调函数的参数index索引值作了parseInt的基数radix,导致出现超范围的radix赋值和不合法的进制解析,才会返回NaN。
也许你还会怀疑索引值和基数radix对应关系的准确性,这时你可以重新定义parseInt函数,再来测试一下:
- function parseInt(str, radix) {
- return str+'-'+radix;
- };
- var a=["1", "2", "3", "4","5",6,7,8,9,10,11,12,13,14,15];
- a.map(parseInt);
输出结果为:["1-0","2-1","3-2","4-3","5-4","6-5","7-6","8-7","9-8","10-9","11-10","12-11","13-12","14-13","15-14"]。
通过此例,再次证明,索引index的起始值从0开始,与radix的对应如前陈述一致,所以才会出现返回NaN的类型值。
这个实例提醒我们在使用两个函数parseInt和map时候要格外小心。同时对于IE6-7不支持map函数的情况也要谨慎或者通过prototype扩展处理。
最后再仔细回顾温习一下:
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() 将把它解析为十进制的整数。
提示和注释
注释:只有字符串中的第一个数字会被返回。
注释:开头和结尾的空格是允许的。
提示:如果字符串的第一个字符不能被转换为数字,那么 parseFloat() 会返回 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
对数组的每个元素调用定义的回调函数并返回包含结果的数组。
array1.map(callbackfn[, thisArg])
参数 |
定义 |
---|---|
array1 |
必需。 一个数组对象。 |
callbackfn |
必需。 一个接受最多三个参数的函数。 对于数组中的每个元素,map 方法都会调用 callbackfn函数一次。 |
thisArg |
可选。 可在 callbackfn 函数中为其引用this 关键字的对象。 如果省略thisArg,则 undefined 将用作this 值。 |
其中的每个元素均为关联的原始数组元素的回调函数返回值的新数组。
如果 callbackfn 参数不是函数对象,则将引发 TypeError 异常。
对于数组中的每个元素,map 方法都会调用 callbackfn 函数一次(采用升序索引顺序)。 不为数组中缺少的元素调用该回调函数。
除了数组对象之外,map 方法可由具有 length 属性且具有已按数字编制索引的属性名的任何对象使用。
回调函数语法
回调函数的语法如下所示:
function callbackfn(value, index, array1)
可使用最多三个参数来声明回调函数。
下表列出了回调函数参数。
回调参数 |
定义 |
---|---|
value |
数组元素的值。 |
index |
数组元素的数字索引。 |
array1 |
包含该元素的数组对象。 |
修改数组对象
数组对象可由回调函数修改。
下表描述了在 map 方法启动后修改数组对象所获得的结果。
map 方法启动后的条件 |
元素是否传递给回调函数 |
---|---|
在数组的原始长度之外添加元素。 |
否。 |
添加元素以填充数组中缺少的元素。 |
是,如果该索引尚未传递给回调函数。 |
元素被更改。 |
是,如果该元素尚未传递给回调函数。 |
从数组中删除元素。 |
否,除非该元素已传递给回调函数。 |
下面的示例阐释了 map 方法的用法。
// Define the callback function.
function AreaOfCircle(radius) { var area = Math.PI * (radius * radius); return area.toFixed(0); } // Create an array. var radii = [10, 20, 30]; // Get the areas from the radii. var areas = radii.map(AreaOfCircle); document.write(areas); // Output: // 314,1257,2827
下面的示例阐释 thisArg 参数的用法,该参数指定对其引用this 关键字的对象。
// Define an object that contains a divisor property and
// a remainder function.
var obj = { divisor: 10, remainder: function (value) { return value % this.divisor; } } // Create an array. var numbers = [6, 12, 25, 30]; // Get the remainders. // The obj argument specifies the this value in the callback function. var result = numbers.map(obj.remainder, obj); document.write(result); // Output: // 6,2,5,0
在下面的示例中,内置 JavaScript 方法用作回调函数。
// Apply Math.sqrt(value) to each element in an array.
var numbers = [9, 16];
var result = numbers.map(Math.sqrt); document.write(result); // Output: 3,4
map 方法可应用于字符串。 下面的示例阐释了这一点。
// Define the callback function.
function threeChars(value, index, str) { // Create a string that contains the previous, current, // and next character. return str.substring(index - 1, index + 2); } // Create a string. var word = "Thursday"; // Apply the map method to the string. // Each array element in the result contains a string that // has the previous, current, and next character. // The commented out statement shows an alternative syntax. var result = [].map.call(word, threeChars); // var result = Array.prototype.map.call(word, threeChars); document.write(result); // Output: // Th,Thu,hur,urs,rsd,sda,day,ay
在以下文档模式中受支持:Internet Explorer 9 标准模式、Internet Explorer 10 标准模式和 Internet Explorer 11 标准模式。Windows 应用商店 应用程序中也支持此项。请参阅版本信息。
在以下文档模式中不受支持:Quirks、Internet Explorer 6 标准模式、Internet Explorer 7 标准模式、Internet Explorer 8 标准模式。
最后再援引一篇文章:JavaScript数组遍历map()的原型扩展http://www.nowamagic.net/librarys/veda/detail/783
在 JavaScript 1.6 里,javascript 数组增加了几个非常有用的方法:indexOf、lastIndexOf、every、 filter、 forEach、 map、 some,其中前两个可以归为元素定位方法,而后面的几个则可以归为迭代(iterative)方法。
遗憾的是:这些新方法并非所有浏览器都支持,在这种情况下,我们就需要自己动手了,在这些介绍的文章中,我们同时提供了在不支持这些新特性的浏览器中的实现方法。
原生方法如下:
1
|
var mappedArray = array.map(callback[, thisObject]);
|
- callback: 要对每个数组元素执行的回调函数。
- thisObject : 在执行回调函数时定义的this对象。
对数组中的每个元素都执行一次指定的函数(callback),并且以每次返回的结果为元素创建一个新数组。它只对数组中的非空元素执行指定的函数,没有赋值或者已经删除的元素将被忽略。
回调函数可以有三个参数:当前元素,当前元素的索引和当前的数组对象。如参数 thisObject 被传递进来,它将被当做回调函数(callback)内部的 this 对象,如果没有传递或者为null,那么将会使用全局对象。
map 不会改变原有数组,记住:只有在回调函数执行前传入的数组元素才有效,在回调函数开始执行后才添加的元素将被忽略,而在回调函数开始执行到最后一个元素这一期间,数组元素被删除或者被更改的,将以回调函数访问到该元素的时间为准,被删除的元素将被忽略。
如果浏览器不支持map方法,也可以按照下面的方式用prototype去扩展:
01
|
<script type= "text/javascript" >
|
02
|
//扩展原型对象
|
03
|
Array.prototype.map = function (fn){
|
04
|
var a = [];
|
05
|
for ( var i = 0; i < this .length; i++){
|
06
|
var value = fn( this [i], i);
|
07
|
if (value == null ){
|
08
|
continue ; //如果函数fn返回null,则从数组中删除该项
|
09
|
}
|
10
|
a.push(value);
|
11
|
}
|
12
|
return a;
|
13
|
};
|
14
|
15
|
//例子,arr为原始数组
|
16
|
var arr = [
|
17
|
{name: 'gonn' , age: 20, sex: '1' , No: '274200' },
|
18
|
{name: 'nowamagic' , age: 30, sex: '0' , No: '274011' },
|
19
|
{name: 'frie' , age: 40, sex: '1' , No: '274212' }
|
20
|
];
|
21
|
|
22
|
//使用map更改数组每项的值,可对数组每一项元素内部进行增删改,也可以通过return null来删除数组的某项
|
23
|
var arr2 = arr.map( function (item, i){
|
24
|
item.sex = item.sex == '0' ? '女' : '男' ;
|
25
|
if (item.name == 'tom' ){
|
26
|
return null ; //删除name为tom的项
|
27
|
}
|
28
|
return {
|
29
|
index: i,
|
30
|
name: item.name,
|
31
|
age: item.age + 30 + i,
|
32
|
sex: item.sex
|
33
|
};
|
34
|
});
|
35
|
|
36
|
console.log(arr2);
|
37
|
</script>
|
在Firefox firebug控制台输出:
1
|
[
|
2
|
Object { index=0, name= "gonn" , age=50, 更多...},
|
3
|
Object { index=1, name= "nowamagic" , age=61, 更多...},
|
4
|
Object { index=2, name= "frie" , age=72, 更多...}
|
5
|
]
|
或者以下方式扩展也可以:
01
|
if (!Array.prototype.map)
|
02
|
{
|
03
|
Array.prototype.map = function (fun /*, thisp*/ )
|
04
|
{
|
05
|
var len = this .length;
|
06
|
if ( typeof fun != "function" )
|
07
|
throw new TypeError();
|
08
|
|
09
|
var res = new Array(len);
|
10
|
var thisp = arguments[1];
|
11
|
for ( var i = 0; i < len; i++)
|
12
|
{
|
13
|
if (i in this )
|
14
|
res[i] = fun.call(thisp, this [i], i, this );
|
15
|
}
|
16
|
|
17
|
return res;
|
18
|
};
|
19
|
}
|
注:map返回的是新数组,它不修改调用的数组。
为了兼容不支持map的浏览器,developer.mozilla.org上给出了map兼容性解决方法。
- // Production steps of ECMA-262, Edition 5, 15.4.4.19
- // Reference: http://es5.github.com/#x15.4.4.19
- if (!Array.prototype.map) {
- Array.prototype.map = function(callback, thisArg) {
- var T, A, k;
- if (this == null) {
- throw new TypeError(" this is null or not defined");
- }
- // 1. Let O be the result of calling ToObject passing the |this| value as the argument.
- var O = Object(this);
- // 2. Let lenValue be the result of calling the Get internal method of O with the argument "length".
- // 3. Let len be ToUint32(lenValue).
- var len = O.length >>> 0;
- // 4. If IsCallable(callback) is false, throw a TypeError exception.
- // See: http://es5.github.com/#x9.11
- if (typeof callback !== "function") {
- throw new TypeError(callback + " is not a function");
- }
- // 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
- if (thisArg) {
- T = thisArg;
- }
- // 6. Let A be a new array created as if by the expression new Array(len) where Array is
- // the standard built-in constructor with that name and len is the value of len.
- A = new Array(len);
- // 7. Let k be 0
- k = 0;
- // 8. Repeat, while k < len
- while(k < len) {
- var kValue, mappedValue;
- // a. Let Pk be ToString(k).
- // This is implicit for LHS operands of the in operator
- // b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk.
- // This step can be combined with c
- // c. If kPresent is true, then
- if (k in O) {
- // i. Let kValue be the result of calling the Get internal method of O with argument Pk.
- kValue = O[ k ];
- // ii. Let mappedValue be the result of calling the Call internal method of callback
- // with T as the this value and argument list containing kValue, k, and O.
- mappedValue = callback.call(T, kValue, k, O);
- // iii. Call the DefineOwnProperty internal method of A with arguments
- // Pk, Property Descriptor {Value: mappedValue, : true, Enumerable: true, Configurable: true},
- // and false.
- // In browsers that support Object.defineProperty, use the following:
- // Object.defineProperty(A, Pk, { value: mappedValue, writable: true, enumerable: true, configurable: true });
- // For best browser support, use the following:
- A[ k ] = mappedValue;
- }
- // d. Increase k by 1.
- k++;
- }
- // 9. return A
- return A;
- };
- }
解惑 [1, 2, 3].map(parseInt) 为何返回[1,NaN,NaN]相关推荐
- ['1','2','3'].map(parseInt)
理解这道题的本质就在于: 对map第一个参数callback传参的理解 对parseInt的传参和转化字符的规则 其实就是考察我们平时对基础知识的API的掌握情况. Array.prototype.m ...
- ['1', '2', '3'].map(parseInt) what why ?
关于map和parseInt的函数解释developer.mozilla.org/zh-CN/docs/- 首先parseInt(string, radix) 接收两个参数,第一个表示被处理的值(字符 ...
- string数组转map_[#x27;1#x27;, #x27;2#x27;, #x27;3#x27;].map(parseInt) 映射解析
parseInt(string,radix) 将一个字符串 string 转换为 radix 进制的整数,radix为介于2-36之间的数. 参数: string要被解析的值.如果参数不是一个字符串, ...
- 掘金100道(2)['1', '2', '3'].map(parseInt) what why ?
一.psrseInt 解析(解析字符串,字符串 => 指定基数的整数) 1 parseInt(string, radix) 接收两个参数,第一个表示被处理的值(字符串),第二个表示为解析时的 ...
- [‘1‘,‘2‘,‘3‘].map(parseInt)结果讲解
一.前言 这是一道前端面试题,先说结果:[1, NaN, NaN] 二.为什么会是这个结果 1. map函数 将数组的每个元素传递给指定的函数处理,并返回处理后的数组,所以 ['1','2','3'] ...
- [前端面试题][‘1‘,‘2‘,‘3‘].map(parseInt)
** [前端面试题]['1','2','3'].map(parseInt)的坑 ** console.(['1','2','3'].map(parseInt)); 乍一看,是不是都以为是输出1,2,3 ...
- 面试官:[‘1‘, ‘2‘, ‘3‘].map(parseInt)的结果是什么?为甚?我:[1, 2, 3]。面试官:你不用来了。
大家好,我是一碗周,一个不想被喝(内卷)的前端.如果写的文章有幸可以得到你的青睐,万分有幸~ 面试官:['1', '2', '3'].map(parseInt)的结果是什么?为甚? 我:[1, 2, ...
- [JS] 关于parseInt的一个小知识:[‘1‘, ‘2‘, ‘3‘].map(parseInt)
主要是在笔试里看到了,自己试下.. let a = ['1', '2', '3'].map(parseInt) console.log(a) 运行结果: 反正当时是做错了,QAQ 查了一下原理,感谢大 ...
- js 用下标获取map值_js map方法处理返回数据,获取指定数据简写方法
map方法处理返回数据,获取指定数据简写方法 前言 后端返回数据为数组列表时,通常比较全面,包含了很多不需要的数据,可以通过 map 方法处理返回数据,筛选出想要的数据 例如 // 返回数据 res ...
最新文章
- Android 编译报错:Could not get resource
- Java中Math3 各种随机数生成器的使用(Random Generator)
- C语言的inline
- 在WPF TreeView中使用复选框
- Qlik助力新西兰最大私人医院提高病患护理水平
- Junit4中的新断言assertThat的使用方法
- 用java写一个博客网站
- 有哪些实用的电脑软件值得推荐?2021电脑装机必备便签软件
- 2022年陕西省职业院校技能大赛中职组网络安全赛项规程
- Svchost.exe病毒的简单处理
- win10计算机打开速度慢,win10电脑系统开机启动速度慢如何解决?
- Jmeter全方面讲解——Jmeter的安装
- 最新整理常见互联网公司职级和薪资一览!
- 侧里——我最钟爱的张国枯照片之Top10来源w
- 打算打造一个最牛iOS培训品牌
- Ubuntu Server 18.04安装后vi命令解决键盘错乱方法和wifi连接之后不能上网
- UNKNOWN.RPT 无法将请求提交后台处理
- 图像二值化_三角阈值法
- python六个标准的数据类型
- 基于jQuery经典扫雷游戏源码
热门文章
- w7系统装天联高级版服务器,w7系统有几个版本你都知道吗?
- Android Studio(IDEA)太占系统盘?帮你移动下
- ROS知识【13】:ubuntu下安装eclipse-CDT【非installor】
- Python 项目依赖包 第三方库 生成requirements.txt的两种方法
- h2 mysql 差别_h2内存数据库和mysql数据库的区别
- sftp 中文乱码 连接后_sftp服务器中文乱码
- python queue_Python-Queue 入门
- vivado中的rtl中电路图无发生成_FPGA零基础学习:数字电路中的组合逻辑
- VUE 新手入门感慨
- java虚拟机内存告警_Java虚拟机总结