I was trying to flatten an object that has two objects in it, so I did the following:
var underscore = require('underscore');
var obj = { a: {x:1}, b: {y:2}};
underscore.reduce(obj, underscore.extend, {});
Unexpectedly, the output that I've got was:
{
'0': 'b',
x: 1,
a: { x: 1 },
b: { y: 2 },
y: 2
}
So then I've tried to wrap extend
in a function:
underscore.reduce(obj, function(memo, o) {
return underscore.extend(memo, o);
}, {});
And got the expected result:
{ x: 1, y: 2 }
Why is there any difference? reduce
expected as the 2nd argument a function that gets two arguments and returns one, and it gets it in both cases. So what am I missing?
reduce
expected as the 2nd argument a function that gets two arguments and returns one...
Not according to the documentation . Underscore passes the iterator four , not two, arguments:
The iterator is passed four arguments: the
memo
, then thevalue
andindex
(orkey
) of the iteration, and finally a reference to the entirelist
.
Consequently, you end up calling extend
(on the first pass) like this:
underscore.extend({}, {x: 1}, 'a', obj)
and then the second pass
underscore.extend({/*...stuff...*/}, {y: 2}, 'b', obj)
The reason the object has a '0': 'b'
attribute is that strings extend into an object containing attributes like '<index>': '<char>'
. This is because _.extend
runs a for...in...
loop on each argument (except the first) and the keys found by doing that to a string are the character indexes (from 0
to str.length - 1
).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.