javascript - 为什么在字符串数组上使用 Array.map(parseInt) 会产生不同的结果

标签 javascript functional-programming parseint

我正在看一个关于销毁所有软件标题的演讲 The Birth and Death of Javascript

在演讲中,Gary Bernhardt 指出了一个 JavaScript 古怪的特性,被赋予了一个整数字符串数组,

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

Array.map() 接受一个函数并返回一个新数组,其中包含将此函数应用于每个运算符的结果。

起初我发现这种行为非常奇怪,parseInt 不是将数字解析为整数吗?

为什么会是 NaN?然后不是 10!!

最佳答案

JavaScript 通常是模仿的主题,因为它看似 unexpected results .

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

然而,它的疯狂是一致的,我怀疑 parseInt 行为背后一定有某种原因。

深入了解正在发生的事情

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

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]

好的,看起来一切正常fine

但为了简洁起见,我决定尝试更多观察

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]

也许毕竟没那么奇怪

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

然后它击中了我。 Array.map(callback) 回调有 3 个参数,(key, index, array),所以如果 parseInt 不只是接受一个参数,而不是 2 个参数。

那肯定会影响它的结果

Turns out parseInt() 函数解析字符串参数并返回指定基数或基数的整数。

语法 parseInt(string, radix);

radix 是数字的基数

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
//...

由于 map 的回调中的第二个参数是索引,因此 radix 根据索引不断变化。

这解释了为什么我的 intParse 函数有效。 我已经明确定义它仅使用带 x 的“parseInt”。

我以为这就是 map 内部发生的事情

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

事实上,这就是正在发生的事情

var intParse = function (x, r, array) { 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)

关于javascript - 为什么在字符串数组上使用 Array.map(parseInt) 会产生不同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24046827/

相关文章:

javascript - S3 CORS 错误永远不会结束

javascript - 如何将相同的 jquery 添加到不同的 div 但具有不同的内容?

python - 如何添加功能

javascript - 为什么 JavaScript 中的 parseInt() 将 "1abc"转换为 1?

javascript - 如何从 HTML 页面中删除多个具有相同类的 div

javascript - 如何让 Mocha 考试不及格

c# - 如何从IObservable请求商品?

javascript - 传递参数数组

javascript - 更改具体名称:value pair in Javascript object

java - 解析子串?