Underscore.js文档解释了_.tap()
函数“点击”到方法链中。 http://underscorejs.org/#tap
我无法效仿他们的榜样:
_.chain([1,2,3,200])
.filter(function(num) { return num % 2 == 0; })
.tap(alert)
.map(function(num) { return num * num })
.value();
=> // [2, 200] (alerted)
=> [4, 40000]
在这种情况下,方法链是什么?我一直认为方法链是链接方法的概念:object.foo().bar().baz()
。
我见过使用这种方法的例子:module.exports = _.tap {}, (connectors) ->
,这也是“点击”对象文字的方法链吗?
答案 0 :(得分:10)
来自fine manual:
<强>链接强>
[...]
调用 chain 将导致所有将来的方法调用返回包装对象。完成计算后,使用值检索最终值。
因此,在Underscore上下文链接与在其他地方链接相同,除了您在包装对象上链接Underscore方法。首先调用_.chain
来获取包装器:
_(obj).chain()
然后你在_.chain
返回的内容上调用Underscore方法,它们也将返回包装对象:
_(obj).chain()
.filter(function(x) { ... })
.map(function(x) { ... })
...
最后你调用_.value
打开链接包装器:
var result = _(obj).chain()
.filter(function(x) { ... })
.map(function(x) { ... })
...
.value();
返回_.tap
。全部tap
does is this:
_.tap = function(obj, interceptor) {
interceptor(obj);
return obj;
};
所以它调用传递的函数interceptor
对迭代的值进行迭代,并返回正在迭代的内容而不对其做任何事情。 _.tap
与以下内容相同:
.map(function(x) { f(x); return x })
但它会使你的意图明确。实际上,_.tap
允许您在不更改数据的情况下查看通过方法链的数据。
答案 1 :(得分:8)
我同意文档中的示例是愚蠢的,因为alert
迭代对象永远不是你想要在真实情况下做的事情(除非你正在调试并希望知道对象的状态2个链式方法 - 但在这种情况下,它可能只是警告[object Object]
; console.log
更合适但不会按预期工作[但我离题])。以下是非链接工作流程的示例:
var x = { a: 1, b: 2, c: 3 };
x = _.filter( x, function( value ){
return ( value % 2 === 0 );
} );
x.length = _.size( x );
x = _.pairs( x );
这种情况真的很适合链接:上面的所有代码实际上都是创建并连续修改一个对象。 Chaining清楚地说明了这一点,并阻止你不断写作。唯一的问题是我声明length
的行 - 它不能完全适合链,因为它是唯一的声明,它不是简单地在对象上运行下划线方法并将结果分配回该对象。这就是tap
的用武之地:你想做一些不容易在链中链接的东西。以下是他对工作流程的看法:
var x = _
.chain( { a: 1, b: 2, c: 3 } )
.filter( function( value ){
return ( value % 2 === 0 );
} )
.tap( function( x ){
x.length = _.size( x );
} )
.pairs()
.value();
答案 2 :(得分:1)
如您所述,方法链接将方法链接在一起。关于_.tap
的关键细节是将每种方法的结果传递给下一个。
_。tap可让您插入结果未通过的方法。将先前方法的结果传递给_tap
之后的方法。这允许在链中处理中间结果而不改变链的结果。
在你的例子中,如果单独调用alert
会破坏链,因为它不会返回任何内容。使用_.tap
会导致上一个方法(filter(function(num) { return num % 2 == 0; })
)的结果传递给以下方法(map(function(num) { return num * num })
)
答案 3 :(得分:1)
示例中的链是filter().tap().map()
:
_.chain([1,2,3,300])
在包含filter
,tap
,map
,value
等方法的下划线包装中包装数组。.tap(alert)
展开filter()
的结果,使用展开的对象调用alert()
,然后将其再次包装并将其返回.value()
返回包装对象(减去包装器)。