Underscore.js:如何链接自定义函数

ave*_*net 22 javascript functional-programming underscore.js

使用Underscore.js,我可以编写以下内容返回42:

_([42, 43]).chain()
    .first()
    .value()
Run Code Online (Sandbox Code Playgroud)

我有自定义函数,不是Underscore.js的一部分double():

function double(value) { return value * 2; };
Run Code Online (Sandbox Code Playgroud)

我希望能够在Underscore链中调用此函数,就像它是Underscore的一部分一样.我想写下以下内容,我想回复84:

_([42, 43]).chain()
    .first()
    .double()
    .value()
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为Underscore没有定义double().我可以使用tap()如下:

_([42, 43]).chain()
    .first()
    .tap(double)
    .value()
Run Code Online (Sandbox Code Playgroud)

这是有效的,但tap将函数应用于其参数并返回参数,而不是函数的结果.所以它看起来像我需要一种tap返回应用于其参数的函数的结果.在Underscore.js中有这样的东西吗?我错过了一些非常明显的东西吗?

ave*_*net 24

没有找到一个tap返回函数运行的返回值,我定义一个我可以take添加到_:

_.mixin({take: function(obj, interceptor) {
    return interceptor(obj);
}});
Run Code Online (Sandbox Code Playgroud)

假设我有:

function double(value) { return value * 2; };
Run Code Online (Sandbox Code Playgroud)

我可以写:

_([42, 43]).chain()
    .first()             // 42
    .take(double)        // Applies double to 42
    .value()             // 84
Run Code Online (Sandbox Code Playgroud)

你可以看一下take作为map在对象上,而不是名单.想试试这个吗?在jsFiddle上查看此示例.

  • @Gabe,我想把它叫做`apply`,但名字已经在函数上定义了,它有一个不同的语义:`f.apply(obj,argArray)`而不是`obj.take(f,argArray)` .你不认为这可能会造成混乱吗?(老实说,因为我不相信自己.) (4认同)

Roa*_*rth 5

所以你有一个自定义功能:

function double(value) { return value * 2; }
Run Code Online (Sandbox Code Playgroud)

您可以使用它mixin来扩展Underscore:

_.mixin({ double:double });
Run Code Online (Sandbox Code Playgroud)

现在您可以从Underscore对象调用您的函数_:

_.double(42); // 84
Run Code Online (Sandbox Code Playgroud)

并从包装的对象返回chain:

_([42, 43]).chain()
  .first()
  .double() // double made it onto the wrapped object too
  .value(); // 84
Run Code Online (Sandbox Code Playgroud)


Cha*_*ers 5

好吧,我刚刚第一次阅读下划线注释源代码.但我认为你可以这样做:

function double(value) { return value * 2; };

var obj = _([42, 43]).addToWrapper({double:double});

obj.chain()
  .first()
  .double()
  .value();
Run Code Online (Sandbox Code Playgroud)

语法/细节可能不正确,但核心点是:当您调用时_([42,43]),您将下划线作为函数调用.执行此操作时,它会实例化一个新对象,然后将大多数下划线函数混合到该对象中.然后,它将该对象返回给您.然后,您可以将自己的函数添加到该对象,并且这些函数都不会污染"_"命名空间本身.

这就是下划线.js代码对我来说的样子.如果我错了,我想找出答案,希望有人会解释原因.

编辑:我实际上已经大量使用了underscore.js大约一个月了,而且我对它非常熟悉.我现在知道它的行为就像我在这里说的那样.当您将_作为构造函数调用时,您将获得自己的"命名空间"(只是一个对象),并且您可以使用addToWrapper()向其添加内容,这些内容显示在您的命名空间中但不会显示在"global""_"中命名空间.所以OP想要的功能已经内置.(而且我用下划线给我留下了深刻的印象,顺便说一下,这是非常好的完成).

  • @Alessandro Vernet - 不,它不会污染_名称空间.这就是它的美丽.当你调用_([42,43])时,它会为你返回一个*全新*命名空间.然后当你添加"double"时,你自己的命名空间将有两倍,但_本身不会. (2认同)