I'm using NodeJS 0.10.13. I'm just curious about the behavior of the following code snippet:
> var a = ['1','2','3']
undefined
> a.map(function(){return path.resolve(arguments[0])})
[ '/Users/user/1',
'/Users/user/2',
'/Users/user/3' ]
> a.map(path.resolve)
TypeError: Arguments to path.resolve must be strings
at exports.resolve (path.js:313:15)
> a.map(path.resolve.bind(path)))
TypeError: Arguments to path.resolve must be strings
at exports.resolve (path.js:313:15)
Why is it that the 2nd and 3rd map calls return an error when the array only has strings? Going to the relevant line in NodeJS's source code yields this:
if (typeof path !== 'string') {
throw new TypeError('Arguments to path.resolve must be strings');
} else if (!path) {
continue;
}
Which makes no sense as to why the arguments are not strings. Does anyone have any clue?
The callback to Array.prototype.map is passed three arguments: current element, index, and the array being traversed.
a.map(path.resolve);
a.map now calls path.resolve using a construct similar to this:
path.resolve.call(undefined, element, index, array);
path.resolve([from ...], to) can accept var args. If you go through the source of path.js
for (var i = arguments.length - 1; i >= -1; i--) {
//..irrelevant lines
var path = arguments[i];
if (typeof path !== 'string') {
throw new TypeError('Arguments to path.resolve must be strings');}
else if (!path) {
continue;
}
}
In the first iteration, path is the third argument, which is an Array.
typeof arrayObject !== 'string' evaluates to true and hence the TypeError
This happens because the parameters passed to each call of the mapped function will get not only the actual elment, but also the array index and the whole array.
To see exactly what parameters gets sent to map, try this:
> var a = ['1', '2', '3'];
['1', '2', '3']
> a.map(function() { return arguments});
[ { '0': '1',
'1': 0,
'2': [ '1', '2', '3' ] },
{ '0': '2',
'1': 1,
'2': [ '1', '2', '3' ] },
{ '0': '3',
'1': 2,
'2': [ '1', '2', '3' ] } ]
Since the object sent to the mapped function (path.resolve in this case) is not a string but an object, you get a TypeError.