使用 下划线, ,我可以编写以下内容 42:

_([42, 43]).chain()
    .first()
    .value()

我有自定义功能,而不是underscore.js的一部分 double():

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

我希望能够在下划线链中调用此功能,就好像它是下划线的一部分一样。我想写以下内容,我想返回 84:

_([42, 43]).chain()
    .first()
    .double()
    .value()

这不能起作用,因为下划线不能定义 double(). 。我可以使用 tap() 如:

_([42, 43]).chain()
    .first()
    .tap(double)
    .value()

这是有效的,但是 tap 将函数应用于其参数并返回参数,而不是函数的结果。所以在我看来,我需要一种 tap 这返回了应用于其参数的函数的结果。 inscore.js中有类似的东西吗?我想念很明显的东西吗?

有帮助吗?

解决方案

找不到 tap 返回通过函数返回的值返回,我定义了一个我可以的 take 并添加到 _:

_.mixin({take: function(obj, interceptor) {
    return interceptor(obj);
}});

然后假设我有:

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

我可以写:

_([42, 43]).chain()
    .first()             // 42
    .take(double)        // Applies double to 42
    .value()             // 84

你可以看 take 作为 map 在对象上,而不是列表。想尝试一下吗?看到这个 JSFIDDLE上的示例.

其他提示

因此,您有一个自定义功能:

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

您可以使用 mixin 扩展下强调:

_.mixin({ double:double });

现在您可以从下划线对象调用您的功能 _:

_.double(42); // 84

并从包裹的对象返回 chain:

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

好吧,我是第一次阅读下划线注释的源代码的新鲜。但是我认为您可以做这样的事情:

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

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

obj.chain()
  .first()
  .double()
  .value();

语法/详细信息可能不正确,但是核心点是:当您致电时 _([42,43]), ,您将其称为函数。当您这样做时,它会实例化新对象,然后将大多数下划线函数混合到该对象中。然后,它将该对象返回给您。然后,您可以将自己的功能添加到该对象中,并且任何一个都不会污染“ _”名称空间本身。

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

编辑:我实际上已经大约使用了一个月的大约一个月,而且我已经非常熟悉了。我现在 知道 就像我在这里说的那样。当您将_调用_作为构造函数函数时,您将获得自己的“命名空间”(只是一个对象),并且可以使用AddTowrapper()在您的名称空间中显示但不在“全局”“ _”中添加内容。名称空间。因此,OP想要的功能已经内置了。(顺便说一句,我给我留下了深刻的印象。

轻松实现这一目标的许多方法,这里有一个这样的解决方案:

  _.chain([42,43])
    .first(1)
    .map(double)
    .first()
    .value();
    // 84

但是,我建议使用 拉姆达 然后,有了自动卷曲和管道 /组成这类任务是微不足道的:

R.pipe(R.head, R.multiply(2))([42, 43]);  // 84

equivalent to:

R.compose(R.multiply(2), R.head)([42, 43]);  // 84

如果您想扩展解决方案以说出前两个项目,而不是按照OP的要求,而不是单个值,那么:

R.pipe(R.take(2), R.map(R.multiply(2)))([42, 43])  // [84, 86]

但是,在ramda r.com中首选。无论哪种方式,对于这样的琐碎任务,它的确更方便且易于使用。

看起来Lodash已确切地实现了您所需的内容:

_.thru(value, interceptor)

从文档中:

此方法就像_.tap一样,除了它返回拦截器的结果

https://lodash.com/docs#thru

map 为此工作?

_([42, 43]).chain()
    .first()
    .map(double)
    .value()

编辑

从文档看来 map 只有在打电话之前将其放置在 first:

_([42, 43]).chain()
    .map(double)
    .first()
    .value()

使用 compose 是处理情况的另一种方法,但我认为添加一个函数 take 正如我之前建议的 是一个更好的解决方案。不过,这是代码的外观 compose:

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

_.compose(
    double,
    _.first,
    _.bind(_.identity, _, [42, 43])
)();

需要通过返回该值的函数提供初始值(在此通过咖喱完成 identity),并且需要在另一个功能中列出,这与您使用的链条相反,这对我来说似乎是不自然的。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top