首先,
我阅读了related articles,感觉它们不适合我,因为我使用的是一系列继承的方法,而不是一些我可以轻易改变的算术函数。其次,谷歌搜索'javascript chaining method'
的结果主要与jQuery和D3有关。看起来,JavaScript chain
方法令人惊讶地记录不足。
我在CoffeeScript中尝试implement underscore。我正在研究_.chain
方法。我正在为newObject
装饰下划线方法,然后将其返回。我有一个名为value
的私有变量,它被认为是由链式方法调用修改的值。在返回的getValue()
上调用newObject
应返回私有value
变量。
由于某些原因,当我在value
上调用方法时,私有newObject
变量没有改变。正确地计算下划线方法,但是在调用函数时它们不会更改。我尝试阅读underscore source code,但似乎他们以完全不同的方式构建链式方法,如果不重构我的下划线对象的方式,我就无法复制。
_。链
_.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]
答案 0 :(得分:1)
问题与闭包的行为有关(毕竟这是javascript)。问题出现在这里:
newObj[name] = (callback, otherVal) ->
value = fn(value, callback, otherVal)
newObj
关闭fn
的值,只要在name
上调用与newObj
相关联的函数时,就会使用该值。问题是fn
的值在chain
函数的整个生命周期中都会发生变化,因此封闭值也会发生变化。特别是,在chain
退出后,您附加到fn
的每个下划线函数的闭包中newObj
的值将是for name, fn of _
中最后一次迭代的函数环。在这种情况下,该函数为chain
,因此当您在示例中调用map
时,当解释器点击value = fn(value, callback, otherVal)
行时,fn
就是chain
功能。
这就是为什么您需要在示例中调用getValue
两次:a.map(...)
在内部调用chain
,因此它返回一个链式链接对象。
为了解决这个问题,我们可以使用IIFE,这样您附加到fn
的函数就可以关闭您想要的实际函数,而不是关闭newObj
。
newObj[name] = ((f) ->
(callback, otherVal) ->
value = f(value, callback, otherVal)
newObj
)(fn)
现在,我们关闭fn
,而不是关闭fn
以便稍后使用(之后,它不会是我们想要的f
),我们立即绑定fn
成为_.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
的当前值。
这是完整的固定版本,在Coffeescript中:
{{1}}
您可以使用您的示例进行检查,看看它现在给出了正确答案。