_.invoke 方法在 Lodash 中如何工作?
How does the _.invoke method work in Lodash?
背景
从关于 invoke 方法的文档中,我读到:
Invokes the method named by methodName on each element in collection, returning an array of the results of each invoked method
因此,我假设以下代码是同义词,但事实并非如此:
_.map(items, function(item) {
return _.omit(item, 'fieldName');
})
_.invoke(items, _.omit, 'fieldName');
在这种情况下,invoke
方法生成一个字符串数组,而 map 方法 return 生成一个项目数组,其中 fieldName
从每个项目中删除。
问题
- 如何使用
invoke
方法获得与 map
函数相同的结果?
- 为什么
invoke
return 字符串数组在这种特殊情况下?
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>
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
.
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
因为函数被应用 到项目 .
因为 Joe Frambach suggested, 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' }
// ]
请务必记下您使用的是哪个版本的 lodash。
v4.11.1 在对集合进行操作时使用 _.invokeMap
:
_.invokeMap([1,2,3], function () {
console.log(this)
})
背景
从关于 invoke 方法的文档中,我读到:
Invokes the method named by methodName on each element in collection, returning an array of the results of each invoked method
因此,我假设以下代码是同义词,但事实并非如此:
_.map(items, function(item) {
return _.omit(item, 'fieldName');
})
_.invoke(items, _.omit, 'fieldName');
在这种情况下,invoke
方法生成一个字符串数组,而 map 方法 return 生成一个项目数组,其中 fieldName
从每个项目中删除。
问题
- 如何使用
invoke
方法获得与map
函数相同的结果? - 为什么
invoke
return 字符串数组在这种特殊情况下?
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>
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
.
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
因为函数被应用 到项目 .
因为 Joe Frambach suggested, 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' }
// ]
请务必记下您使用的是哪个版本的 lodash。
v4.11.1 在对集合进行操作时使用 _.invokeMap
:
_.invokeMap([1,2,3], function () {
console.log(this)
})