为什么在一个字符串数组上使用Array.map(parseInt)会产生不同的结果 [英] Why does using Array.map(parseInt) on an array of strings produce different results

查看:114
本文介绍了为什么在一个字符串数组上使用Array.map(parseInt)会产生不同的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在看一场关于销毁所有软件标题的演讲诞生和死亡的Javascript



在谈话期间,Gary Bernhardt指出了JavaScript的古怪功能,给出了一串整数字符串,

  javascript 
var a = ['10','10','10','10']
console.log a.map(parseInt函数)); // [10,NaN,2,3,4]

数组。 map()接受一个函数并返回一个新数组,其结果是在每个运算符上应用此函数。



我发现行为令人难以置信地奇怪首先,不是 parseInt 将数字解析为一个整数?



为什么它会是 NaN的?然后不是 10 !! 解决方案

JavaScript往往是模仿的主题, a href =https://www.destroyallsoftware.com/talks/wat =nofollow>意外结果。

 < code var a = [] + {} // [Object object] 
var b = {} + [] // 0

然而,它的疯狂是一致的,我怀疑 parseInt 行为必须有一些原因。



到底发生了什么



我首先想到调试 parseInt ,但由于无法调试本地函数,因此我想将它包装在另一个基本上做同样事情的函数中。

  var intParse = function(x){
return parseInt(x);
};

console.log(a.map(parseInt)); // [10,NaN,2,3,4]
console.log(a.map(intParse)); // [10,10,10,10]

好吧,看起来好像一切正​​常很好



但为了简洁起见,我决定尝试一些更多的观察结果

  var a; 

(a = Array(13).join('10,')。split(','))。pop()//尝试数组13'10
a.map (parseInt函数); // [10,NaN,2,3,4,5,6,7,8,9,10,11]

(a = Array(10).join('100,') .split(','))。pop()//尝试数组10'100's
a.map(parseInt); // [100,NaN,4,9,16,25,36,49,64,81]

(a = Array(10).join('7')。split(' ,'))。pop()//尝试数组10'6's
a.map(parseInt); // [7,NaN,NaN,NaN,NaN,NaN,NaN,6,6,6]



< h3>也许它毕竟不是奇怪的

在这一点上看起来很奇怪,它们是一致的(在某种程度上),似乎确实存在模式。



然后它打我。
Array.map(callback)回调需要3个参数,(key,index,array),那么如果 parseInt 不只是一个参数而是2个参数。



这肯定会影响到其结果

结束 parseInt()函数解析一个字符串参数并返回一个指定基数或基数的整数。



语法
parseInt(string,radix);



strong> radix 是数字的基数

  parseInt(10,0)// 10,zero意思是十进制
parseInt(10,1)// NaN,因为在base 1中只允许0
parseInt(10,2)// 2,'10'in binary
parseInt(10,3)// 3,'3'in ternary
// ...

由于 map 的回调函数中的第二个参数是th e索引基数根据索引不断变化。



这解释了为什么我的 intParse 功能工作。
我已经明确定义它只用x来使用'parseInt'。



我认为这是地图内发生的事情

  var intParse = function(x){return parseInt(x);} 

事实上,这是发生了什么

  var intParse = function(x,r,数组){return parseInt(x,r);} 

函数是
,不会假设传入的参数是这样的


  var a = ['10',' 10','10','10'] 
var intParse = function(){
return parseInt.apply(this,arguments);
}
console.log(a.map(parseInt)); // [10,NaN,2,3,4]
console.log(a.map(intParse)); // [10,NaN,2,3,4]



经验教训



这是一个很好的探索,我认为我的学习比我想象的要多一点 parseInt



更重要的是,我想到当程序以一种意想不到的方式行事时,这很可能是有原因的。

最后,如果你想正确地包装一个函数,使用 .apply(this,arguments)


I was watching a talk on destroy all software title The Birth and Death of Javascript

during the talk Gary Bernhardt pointed out a JavaScript quirky features, were given an array of integer strings,

javascript
var a = ['10','10','10','10']
console.log(a.map(parseInt)); // [10, NaN, 2, 3, 4]

Array.map() takes a function and returns a new array with the result of applying this function on each operator.

I found the behavior incredibly bizarre at first, doesn't parseInt parse a number to an integer?

why would it be NaN? and then not 10!!

解决方案

JavaScript is often the subject of parody, for its seemingly unexpected results.

var a = []+{} // [Object object]
var b = {}+[] // 0

However there is consistency in its madness, and I suspected the parseInt behavior must have some reason behind it.

Getting to the bottom of what's happening

I first thought of debugging parseInt, but since couldn't debug a native function, I thought of wrapping it around another function that basically does the same thing.

var a = ['10','10','10','10']
var intParse = function (x) {
    return parseInt(x);
};

console.log(a.map(parseInt)); // [10, NaN, 2, 3, 4]
console.log(a.map(intParse)); // [10,10,10,10]

Ok so it seems like everything is working fine

But just for the sake of brevity I decided to try some more observations

var a;

(a = Array(13).join('10,').split(',')).pop()  // try array of 13 '10's
a.map(parseInt); // [10, NaN, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

(a = Array(10).join('100,').split(',')).pop() // try array of 10 '100's
a.map(parseInt); // [100, NaN, 4, 9, 16, 25, 36, 49, 64, 81]

(a = Array(10).join('7,').split(',')).pop()   // try array of 10 '6's
a.map(parseInt); // [7, NaN, NaN, NaN, NaN, NaN, NaN, 6, 6, 6]

Maybe it's not that weird after all

At this point as weird as the results may seem, they are consistent (in some way), there certainly seems to be a pattern.

It then hit me. Array.map(callback) the callback takes 3 parameters, (key, index, array), so what if parseInt doesn't just take one parameter but 2 instead.

That would certainly had an effect on its results

Turns out The parseInt() function parses a string argument and returns an integer of the specified radix or base.

Syntax parseInt(string, radix);

the radix is the base of the number

parseInt("10", 0) // 10, zero meant decimal
parseInt("10", 1) // NaN, since only 0 is allowed in base 1
parseInt("10", 2) // 2, '10' in binary
parseInt("10", 3) // 3, '10' in ternary
//...

Since the second argument in map's callback is the index the radix kept changing according to the index.

This explains why my intParse function worked. I had specifically defined that it uses 'parseInt' with just x.

I thought this was what's happening inside map

var intParse = function (x) { return parseInt(x);}

When in fact this is what was happening

var intParse = function (x, r, array) { return parseInt(x, r);}

What I should've done when wrapping the function was to not assuming the arguments that where being passed like so

var a = ['10','10','10','10']
var intParse = function () {
    return parseInt.apply(this, arguments);
}
console.log(a.map(parseInt)); // [10, NaN, 2, 3, 4]
console.log(a.map(intParse)); // [10, NaN, 2, 3, 4]

Lessons learned

This was a nice exploration, I think I wound up learning a bit more than I thought I would about parseInt.

More importantly tho I was reminded that when programs act in an unexpected way, it is most likely for a reason.

Finally, if one wants to properly wrap a function use .apply(this, arguments)

这篇关于为什么在一个字符串数组上使用Array.map(parseInt)会产生不同的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆