为什么在这两种情况下,underscore.reduce的行为不同?

时间:2014-06-12 15:14:36

标签: javascript node.js underscore.js

我试图压扁一个有两个对象的对象,所以我做了以下几点:

var underscore = require('underscore');
var obj = { a: {x:1}, b: {y:2}};
underscore.reduce(obj, underscore.extend, {});

出乎意料的是,我得到的输出是:

{ 
   '0': 'b',
   x: 1,
   a: { x: 1 },
   b: { y: 2 },
   y: 2 
}

然后我尝试将extend包裹在一个函数中:

underscore.reduce(obj, function(memo, o) {
   return underscore.extend(memo, o);
}, {});

得到了预期的结果:

{ x: 1, y: 2 }

为什么会有什么不同? reduce期望作为第二个参数获得两个参数并返回一个参数,并且在两种情况下都获得它。那我错过了什么?

1 个答案:

答案 0 :(得分:4)

  

reduce期望作为第二个参数获得两个参数并返回一个...

不符合the documentation。 Underscore传递迭代器四个,而不是两个参数:

  

迭代器传递四个参数:memo,然后是迭代的valueindex(或key),最后是对整个{的引用{1}}。

因此,您最终会调用list(在第一次传递时),如下所示:

extend

然后是第二遍

underscore.extend({}, {x: 1}, 'a', obj)

对象具有underscore.extend({/*...stuff...*/}, {y: 2}, 'b', obj) 属性的原因是字符串扩展到包含'0': 'b'等属性的对象。这是因为'<index>': '<char>'在每个参数(第一个除外)上运行_.extend循环,并且通过对字符串执行此操作而找到的键是字符索引(从for...in...到{{1} })。