Javascript 在CoffeeScript中重新实现下划线链接

Javascript 在CoffeeScript中重新实现下划线链接,javascript,coffeescript,underscore.js,Javascript,Coffeescript,Underscore.js,首先, 我读了这篇文章,觉得它们不适合我,因为我使用了一系列我继承的方法,而不是一些我可以轻易改变的算术函数。其次,谷歌搜索“javascript链接方法”的结果主要与jQuery和D3有关。JavaScriptchain方法似乎文档不足,令人惊讶 我正试着用咖啡脚本写。我正在研究\uu.chain方法。我将下划线方法修饰为newObject,然后返回它。我有一个名为value的私有变量,假设它是通过链式方法调用修改的值。对返回的newObject调用getValue()应返回私有value变量

首先, 我读了这篇文章,觉得它们不适合我,因为我使用了一系列我继承的方法,而不是一些我可以轻易改变的算术函数。其次,谷歌搜索“javascript链接方法”的结果主要与jQuery和D3有关。JavaScript
chain
方法似乎文档不足,令人惊讶

我正试着用咖啡脚本写。我正在研究
\uu.chain
方法。我将下划线方法修饰为
newObject
,然后返回它。我有一个名为
value
的私有变量,假设它是通过链式方法调用修改的值。对返回的
newObject
调用
getValue()
应返回私有
value
变量

由于某种原因,当我调用
newObject
上的方法时,private
value
变量没有改变。下划线方法的格式正确,但在调用函数时不会更改。我试着阅读,但他们似乎以一种完全不同的方式构建了there-chain方法,如果不重新构造下划线对象的方式,我就无法复制这种方法

\uuu.chain

_.chain = (v) ->
  newObj = {}
  value = v
  newObj.getValue = -> value
  for name, fn of _
    if typeof fn is 'function'
      newObj[name] = (callback, otherVal) ->
        value = fn(value, callback, otherVal)
        newObj
  newObj
示例:

var a = _.chain([1,2,3,4]);
a.map(function(value) {
  return value + 5;
})
a.getValue().getValue()
>>>[1, 2, 3, 4]

问题与闭包的行为有关(毕竟这是javascript)。问题出现在这里:

newObj[name] = (callback, otherVal) ->
  value = fn(value, callback, otherVal)
  newObj
fn
的值关闭,在
newObj
上调用与
name
关联的函数时使用。问题在于,
fn
的值在
函数的整个生命周期中都会发生变化,因此闭合值也会发生变化。特别是,在退出
chain
之后,附加到
newObj
的每个下划线函数的闭包中的
fn
值将是在
循环的
中最后迭代的函数。在本例中,该函数是
chain
,因此在示例中调用
map
时,当解释器点击
value=fn(value,callback,otherVal)
行时,
fn
就是
chain
函数

这就是为什么在示例中需要调用
getValue
两次:
a.map(…)
在内部调用
chain
,因此它返回一个链接的对象

为了解决这一问题,我们可以使用,这样,您附加到
newObj
的函数将关闭您想要的实际函数,而不是关闭
fn

newObj[name] = ((f) ->
  (callback, otherVal) ->
    value = f(value, callback, otherVal)
    newObj
  )(fn)
现在,我们关闭
f
,而不是关闭以后使用的
fn
(以后不再是我们想要的
fn
),我们立即将其绑定为
fn
的当前值

以下是完整的固定版本,使用Coffeescript:

_.chain = (v) ->
  newObj = {}
  value = v
  newObj.getValue = -> value
  for name, fn of _
    if typeof fn is 'function'
      newObj[name] = ((f) ->
        (callback, otherVal) ->
          value = f(value, callback, otherVal)
          newObj
      )(fn)
  newObj

你可以用你的例子检查一下,看看它现在给出了正确的答案。

@Mathletics自己实现某个东西是理解所说的东西是如何工作的一个很好的方法。一个更好的问题是:为什么需要调用
getValue
两次?我敢打赌,您需要这样做的原因与函数不工作的原因相同。