Thursday, June 20, 2019

Array.prototype.map(parseInt) tricky question

When I ran the following JS
['1', '7', '11'].map(parseInt);
I surprisingly saw the result [1, NaN, 3] instead of [1, 7, 11]. But if we try parseFloat
['1', '7', '11'].map(parseFloat);
the result is correct [1, 7, 11]
If we try the extended form of parseInt
['1', '7', '11'].map(i => parseInt(i));
we get the proper outcome as well.

So why is it so messy with the short parseInt?
There are two reasons for that.

1. The expression
['1', '7', '11'].map(parseInt);
is not equivalent to
['1', '7', '11'].map(i => parseInt(i));
it is equivalent to
['1', '7', '11'].map((val, index, arr) => parseInt(val, index, arr));
Array.prototype.map() function accepts 3 arguments - (elementValue, elementIndex, array). If we skip 2nd and 3rd arguments - they are passed as undefined.

2. The parseInt function expects 2 arguments - (stringValue, radix). If radix is undefined, null, false, 0 then the default radix is used - 10.

So let's have a look why we get [1, NaN, 3].
First element = parseInt('1', 0). Radix 0 is invalid argument, so the default 10 radix is used. 1 with radix 10 is 1.
Second element = parseInt('7', 1). The character '7' doesn't exists in 1-based numeral system, that's why we get NaN.
Third element = parseInt('11', 2). '11' in binary system is 3.

No comments:

Post a Comment