undercore.js_.tap()函数什么是方法链

Underscore.js _.tap() function what is a method chain?

本文关键字:什么 方法 函数 js tap undercore      更新时间:2024-01-12

Undercore.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) ->,那么这是否"点击"了对象文字的方法链?

来自精细手册:

链接
[…]
调用将导致所有未来的方法调用返回包装的对象。完成计算后,使用检索最终值。

因此,在Underscore上下文中进行链接与在其他地方进行链接相同,只是在包装的对象上链接Underscore方法。首先调用_.chain获取包装:

_(obj).chain()

然后,您就_.chain返回的内容调用Undercore方法,它们也将返回封装的对象:

_(obj).chain()
      .filter(function(x) { ... })
      .map(function(x) { ... })
      ...

最后调用_.value打开链接包装器:

var result = _(obj).chain()
                   .filter(function(x) { ... })
                   .map(function(x) { ... })
                   ...
                   .value();

返回_.taptap所做的就是:

_.tap = function(obj, interceptor) {
  interceptor(obj);
  return obj;
};

因此,它对正在迭代的值调用传递的函数interceptor,并返回正在迭代的内容,而不对其执行任何操作。_.tap与:相同

.map(function(x, func) { func(x); return x })

但它表明了你的意图。实际上,_.tap允许您在不更改数据的情况下窥探通过方法链的数据。

我同意文档中的例子是愚蠢的,因为alert迭代对象在实际情况下从来都不是你想做的事情(除非你正在调试并想知道对象在两个链接方法之间的状态——但在这种情况下,它可能只会提醒[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 );

这种场景确实适合链接:上面所有的代码本质上都是创建和串行修改一个对象。链接可以让你明白这一点,并阻止你继续写作业。唯一的问题是我声明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();

示例中的链是filter().tap().map():

  • _.chain([1,2,3,300])在下划线包装器中包装数组,该包装器具有filtertapmapvalue等方法
  • .tap(alert)filter()中展开结果,用展开的对象调用alert(),然后再次将其展开并返回
  • .value()返回被包装的对象(减去包装器)

方法链接,正如您所描述的,将方法彼此链接。关于_.tap,关键细节是每个方法的结果都会传递到下一个

_.tap允许您插入一个结果未通过的方法。上一个方法的结果被传递给_tap之后的方法。这允许在不改变链的结果的情况下处理链内的中间结果。

在您的示例中,如果单独调用alert,它将断开链,因为它不会返回任何内容。使用_.tap,将上一个方法(filter(function(num) { return num % 2 == 0; }))的结果传递到下一个方法中(map(function(num) { return num * num })