我正在尝试理解下划线的invoke()
功能,但我在一些方面遇到了麻烦。这是来自注释源的代码:
_.invoke = function(obj, method) {
var args = slice.call(arguments, 2);
var isFunc = _.isFunction(method);
return _.map(obj, function(value) {
var func = isFunc ? method : value[method];
return func == null ? func : func.apply(value, args);
});
};
在这个例子中:
_.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
=> [[1, 5, 7], [1, 2, 3]]
我明白发生了什么事;但是,在源代码中,我不理解args
的功能。在什么样的情况下需要使用其他参数?
我也是编程的新手,我正在努力解决apply
在这里的使用方式。我猜这是因为我不完全理解invoke
的使用,即使用args
。不过,在查看Mozilla's documentation中提供的示例时,一个示例使用了Math.max.apply(*null*, numbers)
,那么为什么它会在源代码中应用于value
?
答案 0 :(得分:4)
如果您查看下划线invoke
文档,则会看到:
你知道吗?所有使用对列表中的每个值调用
methodName
命名的方法。 传递给invoke的任何额外参数都将被转发到方法调用。
apply
和args
的魔法都会被使用,因此您可以使用一些参数在invoke
中触发该方法。
args
?看一下join
数组方法 - 它将元素连接成一个字符串,如果我们传递一些东西 - 它将被用作分隔符。
var things = ['apple', 'banana', 'mango'];
things.join('#') // 'apple#banana#mango'
因此,join
可以接受参数。让我们现在与invoke
一起使用。
var manyThings = [
['apple', 'banana', 'mango'],
['pepsi', 'fanta', 'sprite'],
['bear', 'wolf', 'parrot']
];
// Pass '#' as a third argument - is like join('#')
console.log(_.invoke(arr, 'join', '#'));
// ["apple#banana#mango", "pepsi#fanta#sprite", "bear#wolf#parrot"]
我们将'#'传递给join
方法!当我们使用其他参数时就是这种情况。
它如何运作?
var args = slice.call(arguments, 2);
我们存储传递给invoke
的所有参数,从第三个开始(第一个是列表,第二个是方法名称)。我们在manyThings
案例中存储了“#”。
invoke
之后传递的每个methodName
参数都成为此methodName
函数的参数。
_.invoke(obj, 'methodName', '#', 2, false, '--')
// It's like do obj.methodName('#', 2, false, '--')
args
的函数 - 存储传递的参数以在方法中使用它。
apply
?当我们拥有所有这些参数时,我们已准备好将它们传递给我们在这里的方法:
var func = isFunc ? method : value[method];
你知道吗?我们采用了value[method]
函数。在此函数深处的某处使用this
。因此,为了能够使用右this
(manyThings数组)在正确的对象上触发该函数,我们需要apply
。我们将args
作为第二个参数传递给apply
(在我们的例子中,它是'#')。
这是如何运作的,我希望你现在能有更好的理解。