A Silly JavaScript Interview Question

Here’s the question, which I found in a thread on Hacker News.

Explain this behavior:

['1','1','1'].map(parseInt) returns [1, NaN, 1]
['1','1','1'].map(n => parseInt(n)) returns [1, 1, 1]

Obviously this is a completely ridiculous question and I would seriously question why anyone would ask this during an interview. But that doesn’t mean we can’t have fun trying to find the answer.

I was stumped at first, especially when I tried playing with the input:

['2','2','2'].map(parseInt)
-> [2, NaN, NaN]

Ok, so let’s try to understand what the map function actually does.

['1','1','1'].map(function() { console.log(arguments) })
-> ["1", 0, Array(3)]
-> ["1", 1, Array(3)]
-> ["1", 2, Array(3)]

(Note that the arguments object is not available in arrow functions) Ok, so this seems like it’s part of the answer - map actually passes 3 arguments to the callback function: the current element, the current index, and the array map was called upon.

So what about parseInt?

parseInt('5')
-> 5
parseInt('5',2)
-> NaN
parseInt('5',10)
-> 5
parseInt('A')
-> NaN
parseInt('A',16)
-> 10

The parseInt function actually takes 2 parameters - the value to parse and the base (or radix) of the value. So our original code snippet is actually equivalent to the following:

// ['1','1','1'].map(parseInt) is equivalent to
parseInt('1',0)
-> 1
parseInt('1',1)
-> NaN
parseInt('1',2)
-> 1

I was surprised that parseInt('1',0) actually returns the correct value, but according to the documentation passing 0 as the base/radix is equivalent to passing undefined which means parseInt will attempt to infer the base/radix, which it does correctly. parseInt('1',2) just means parsing the number 1 in binary, which is perfectly valid.

I initially assumed that this was just some strange quirk of JavaScript, but it’s actually just an unfortunate interaction between 2 APIs. Nothing broken here. What a silly question.