underscore.js:如何链接自定义功能
-
08-10-2019 - |
题
使用 下划线, ,我可以编写以下内容 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一样,除了它返回拦截器的结果
做 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
),并且需要在另一个功能中列出,这与您使用的链条相反,这对我来说似乎是不自然的。