JavaScript - 函数中的函数?

3

最近我使用了一个很好的适用于node.js的库叫做Kue
我想更好地理解它是如何工作的,于是我开始阅读它的代码...

然后,我发现了一段代码,我的脑海里立刻浮现出“WTF!!?!@$@!$”这样的字眼...
这是代码:

function get(obj) {
  var pending = 0
    , res = {}
    , callback
    , done;

  return function _(arg){
    switch (typeof arg) {
      case 'function':
        callback = arg;
        break;
      case 'string':
        ++pending;
        obj[arg](function(err, val){
          if (done) return;
          if (err) return done = true, callback(err);
          res[arg] = val;
          --pending || callback(null, res);
        });
        break;
    }
    return _;
  };
}

这个被用于如下情况:

exports.stats = function(req, res){
  get(queue)
    ('inactiveCount')
    ('completeCount')
    ('activeCount')
    ('failedCount')
    ('delayedCount')
    ('workTime')
    (function(err, obj){
      if (err) return res.send({ error: err.message });
      res.send(obj);
    });
};

.
.
.

这些是关于函数的函数吗?它们如何彼此了解?第7行的下划线“_”代表什么意思?

请问有人能帮我理解一下发生了什么吗?:)


在Javascript中,你可以这样做。你也可以像其他语言中的变量一样将一个函数传递给另一个函数。 - Pradeep Pati
_ 是函数名。它就像其他函数名一样,只是一个非常简短和奇怪的名字。 - Pokey
1个回答

7

函数确实可以返回函数。例如,看看这个函数:

function func(text) {
    alert(text);
    return func;
}

显然,任何对func的调用的返回值都将是func,因此您可以像这样使用它:
func("hello")("world");

...然后你会收到两个警报:首先是“hello”,然后是“world”。

接下来,有一种被称为命名函数表达式的东西。您可能之前见过匿名函数表达式:

doSomething(thing, function(err) {
    // operation completed or something
});

当然,这对于简单的事情来说非常好,但有时您希望函数具有名称,以便它可以引用自己。正如Kolink所提到的那样,如果您只想递归,那么就有arguments.callee,它指的是当前正在执行的函数,但还有另一种方式:您可以给该函数一个仅在函数内部可见的名称,同时仍然将其作为函数表达式:

doSomething(thing, function myself(err) {
    //                      ^^^^^^
    // now I can refer to myself as myself!
});

下划线是一个有效的标识符,所以它们基本上只是将这些技术结合起来,可能会难以理解。

“无法从函数内部引用该函数” - 不正确。arguments.callee - Niet the Dark Absol
非常感谢!现在意思清晰多了... :P - Alex Zak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接