如何理解下划线的调用

时间:2016-04-01 16:27:22

标签: javascript underscore.js

我正在尝试理解下划线的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

注意:我上面写了很多文章,包括thisthisthis以及其他几个视频,但我仍在努力。

1 个答案:

答案 0 :(得分:4)

如果您查看下划线invoke文档,则会看到:

  

对列表中的每个值调用methodName命名的方法。 传递给invoke的任何额外参数都将被转发到方法调用

你知道吗?所有使用applyargs的魔法都会被使用,因此您可以使用一些参数在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(在我们的例子中,它是'#')。

这是如何运作的,我希望你现在能有更好的理解。