问题:
把一个['1', '2', '3']
的数组转换成[1,2,3]
很自然的, 我们会这么写:
['1','2', '3'].map(parseInt);
但这却得不到我们想要的结果, 会变成
[1, NaN, NaN]
但如果我们给parseInt
这个函数包一下,
['1','2', '3'].map(function(n){ return parseInt(n)});
得到的却是正确的结果。
下面就是要讲一下为什么?
事实上, 第一种写法, 放了2个错误:
- 在js中,
map
实际上调用的函数是一个多参数函数, 即function(value, index, array)
, 更详细的说明是MDN的说明:
> callback is invoked with three arguments: the value of the element, the index of the element, and the Array object being traversed.
也就是说, 第一种写法实际上是这样的:
['1','2','3'].map(function(value,index,array){
return parseInt(value, index, arrary);
});
然后这里涉及到第二个错误了。
- parseInt也是一个多参数函数;具体定义是
parseInt(string, radix);
, radix就是进制, MSD还强调Always specify this parameter to eliminate reader confusion and to guarantee predictable behavior.
根据上面展开的函数, 在对’1’执行的是parseInt('1', 0);
, 这里要注意, js中会把多余的参数给忽略了~
但radix参数是零的时候, 他会根据第一个string来做判断, 这里是当十进制了。 所以执行成功。
接下的’2’肯定就错啦, radix不能是1进制。
那 parseInt('3', 2);
为什么错, 不是有2进制么? 你见过2进制中有3的么。。。
所以, 第一种写法结果是符合js的预期的, 虽然他不符合我们的预期。