invoke方法在Lodash中是如何工作的

How does the _.invoke method work in Lodash?

本文关键字:工作 何工作 方法 Lodash invoke      更新时间:2023-09-26

背景

从关于invoke方法的文档中,我读到:

在集合中的每个元素上调用由methodName命名的方法,返回每个被调用方法的结果数组

因此,我假设以下代码是同义的,但事实并非如此:

_.map(items, function(item) {
    return _.omit(item, 'fieldName');
})
_.invoke(items, _.omit, 'fieldName');

在这种情况下,invoke方法生成一个字符串数组,而map方法返回一个从每个项中删除fieldName的项数组。

问题

  • 如何使用invoke方法来获得与map函数相同的结果
  • 为什么invoke在这种特殊情况下返回字符串数组

var items = [{id:1, name:'foo'}, 
             {id:2, name:'bar'}, 
             {id:3, name:'baz'}, 
             {id:4, name:'qux'}];
console.log(
    _.invoke(items, _.omit, 'id')
);
console.log(
    _.map(items, function(item) {
        return _.omit(item, 'id');
    })
);
<script src="https://getfirebug.com/firebug-lite-debug.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.3.1/lodash.min.js"></script>

确保注意您使用的是哪种版本的lodash。

v4.11.1在对集合进行操作时使用_.invokeMap

_.invokeMap([1,2,3], function () {
    console.log(this)
})
var result = _.invoke(items, fn, extraArgs)

相当于

var result = [];
for (var i=0; i<items.length; i++) {
  result.push( fn.apply(items[i], extraArgs) );
}

因此,如果你想要与你的地图相同的结果,那就是

_.invoke(items, function() {
  return _.omit(this, 'id');
})

唯一的区别是item不是函数的参数,而是需要使用this,因为函数应用于项

invoke将函数作为实例方法调用。

例如,

[
(new Date()).toString(),
(new Date()).toString(),
(new Date()).toString()
]

可以重写为:

_.invoke([new Date(), new Date(), new Date()], 'toString')

它大致类似于map,其中map传递一个函数,但invoke传递一个实例的方法。

如果你真的想让invoke在这里为你工作,那么我想你可以这样做:

var items = [{id:1, name:'foo'}, 
             {id:2, name:'bar'}, 
             {id:3, name:'baz'}, 
             {id:4, name:'qux'}];
_.invoke(items, function() { return _.omit(this, 'id') });
// => [Object {name="foo"}, Object {name="bar"}, Object {name="baz"}, Object {name="qux"}]

但你不应该那样做。只需使用map即可。

正如Joe Frambach所建议的,map()更适合于此。

var collection = [
    { id:1, name:'foo' },
    { id:2, name:'bar' },
    { id:3, name:'baz' },
    { id:4, name:'qux' }
];
_.map(collection, _.ary(_.partialRight(_.omit, 'id'), 1));
// → 
// [
//   { name: 'foo' },
//   { name: 'bar' },
//   { name: 'baz' },
//   { name: 'qux' }
// ]