前言
题目:['1', '2', '3'].map(parseInt) what & why ?
运行结果
[1, NaN, NaN]
解题思路
- 从map函数的内部实现开始探究
- parseInt函数的传参探究
map方法的内部实现
- 源码
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. 将O赋值为调用map方法的数组.
var O = Object(this);
// 2.将len赋值为数组O的长度.
var len = O.length >>> 0;
// 3.如果callback不是函数,则抛出TypeError异常.
if (Object.prototype.toString.call(callback) != "[object Function]") {
throw new TypeError(callback + " is not a function");
}
// 4. 如果参数thisArg有值,则将T赋值为thisArg;否则T为undefined.
if (thisArg) {
T = thisArg;
}
// 5. 创建新数组A,长度为原数组O长度len
A = new Array(len);
// 6. 将k赋值为0
k = 0;
// 7. 当 k < len 时,执行循环.
while(k < len) {
var kValue, mappedValue;
//遍历O,k为原数组索引
if (k in O) {
//kValue为索引k对应的值.
kValue = O[ k ];
// 执行callback,this指向T,参数有三个.分别是kValue:值,k:索引,O:原数组.
mappedValue = callback.call(T, kValue, k, O);
// 返回值添加到新数组A中.
A[ k ] = mappedValue;
}
// k自增1
k++;
}
// 8. 返回新数组A
return A;
};
}
这个过程主要分为以下几步:
1、判断this是否存在,也就是作用的数组存不存在
2、判断数组的长度,并且获取数组长度
3、检测callback是否是函数
4、生成一个长度相等的空数组
5、循环调用数组中的每个元素,将每个元素传入callback,并且获取到返回值
6、返回新生成的数组
那么问题来了,会是哪一步出现问题了呢
mappedValue = callback.call(T, kValue, k, O);
仔细阅读源码,发现其他步骤都不会出现问题,只是生成的值出现了偏差,那么我们将怀疑的眼光放到这一步上,我们会发现,循环执行的步骤如下:
parseInt.call(undefined, '1', 0, ['1', '2', '3']);
parseInt.call(undefined, '2', 1, ['1', '2', '3']);
parseInt.call(undefined, '3', 2, ['1', '2', '3']);
返回的结果是:
1
NaN
NaN
刚好是我们得到的结果。那么会什么会产生NaN呢,让我们一起探索一下parseInt的接收参数。
parseInt方法详解
- 接收的参数
string:接收的参数。 radix:进制。比如我们常说的二进制,十进制等。
- 返回值
如果无法解析,返回NaN。
结果分析
parseInt.call(undefined, '1', 0, ['1', '2', '3']);
parseInt.call(undefined, '2', 1, ['1', '2', '3']);
parseInt.call(undefined, '3', 2, ['1', '2', '3']);
这是执行的代码,我们改的简单一点,如下所示:
parseInt('1', 0);
parseInt('2', 1);
parseInt('3', 2);
我们逐个分析:
parseInt('1', 0);
0就相当于十进制,所以,直接返回的结果是1。
parseInt('2', 1);
1代表的是一进制,并不存在,因为一进制无法表示任何东西,所以返回NaN。
parseInt('3', 2);
2代表的是二进制,而二进制中,只能出现1和0两个数字,比如上述代码中的3,根本无法转化成相对应的整数,所以返回NaN。
总结
通过这道题目,我清楚的了解了两个东西:
- map是如何实现的(原理)
- parseInt的第二个参数的用法