参考链接
在做笔试题时遇到这样下面这样一个问题
['103','101','1000010'].map(parseInt)
一开始,想当然地以为输出结果是103,101,1000010。
但当我们使用控制台输出时,眉头一皱,发现事情并没有那么简单:
[101, NaN, 66] // output
我们来看一下MDN上关于map方法的介绍
var new_array = arr.map(function callback(currentValue[, index[, array]]) {
// Return element for new_array
}[, thisArg])
map
map接收两个参数,一个是callback,一个是this.
-
callback
生成新数组元素的函数,使用三个参数:
currentValue--->callback表示数组中正在处理的当前元素,necessary必选参数。index--->callback数组中正在处理的当前元素的索引,可选参数。array--->callback方法被调用的数组,可选参数。 -
thisArg可选
执行
callback函数时使用的this 值,如果省略,则值为undefined。如果this的值为null或者undefined则默认指向window.
通过下面这个例子我们就能大致掌握map的用法。
var numbers = [1, 4, 9];
var roots = numbers.map(Math.sqrt);
// roots的值为[1, 2, 3], numbers的值仍为[1, 4, 9]
接下来,我们再回顾一下这样一个知识点:
参数传递
Javascript中的函数可以使用任意数量的参数调用,即使它们不等于声明的函数参数的数量。缺少的参数被视为未定义,而多余的参数会被忽略(但会存储在类似数组的参数对象中)。*
function foo(x, y) {
console.log(x);
console.log(y);
}
foo(1, 2); // 1, 2
foo(1); // 1, undefined
foo(1, 2, 3); // 1, 2
parseInt
我们注意到在Number原型上也有一个parseInt方法,全局对象上也有一个parseInt方法。那他们两个之间存在什么关系呢?
Number.parseInt === parseInt // 输出为true
说明两个指向同一个对象。
parseInt的用法
parseInt有两个参数:string和radix(进制)。如果提供的radix(进制)为空或者为假值,进制(基数)默认设置为10。radix 为介于2-36之间的数。
有了上面的知识,我们再回过头来看这道笔试题:
['103','101','1000010'].map(parseInt)
我们来分析一下,它的执行流程:
上面的写法与下面其实是等价的
['103','101','1000010'].map(parseInt(currentValue,index,['103','101','1000010']))
第一次循环
parseInt('103',0,['103','101','1000010'])//因为0是假,所以使用默认`radix`为10,对于['103','101','1000010']这个多余的参数则会被忽略,所以输出103
第二次循环
parseInt('101',1,['103','101','1000010'])//radix 为介于2-36之间的数。当radix===1时会返回NaN
//
parseInt('0000000',1)
第三次循环
parseInt('1000010',2,['103','101','1000010'])// 字符串则会被当成是二进制字符串解析,所以输出66
parseInt的注意事项
我们来看这样一个例子:
parseInt('12345',4) //这个题目会输出什么呢?
在四进制中,是不存在4和5的,那么parseInt会对其进行怎样的处理呢?
parseInt('12345',4) // 输出27 3*4^0+2*4^1+1*4^2=27
基于此,我们可以合理推测parseInt会忽略大于等于4的字符。
那如果string后面还出现了小于4的字符呢?比如
parseInt('1234331',4)// 同样输出27
基于此,我们可以做出这样的推论,只要在字符串中出现大于等于radix的数值,字符串就会从此位置开始被截断,parseInt会忽略后面的字符。
通过这道笔试题,让我更加发现了自己的不足,以后要继续加油。