以下代码定义了两个函数lines
和circles
,它们分别返回一个函数f
和g
。函数f
和g
相等(() -> size
)仅为了简单起见,但通常它们是变量size
的不同函数。
lines = () ->
size = 10 # default value
f = () -> size
f.size = (_) ->
size = _
f
f
circles = () ->
size = 15 # default value
g = () -> size
g.size = (_) ->
size = _
g
g
在控制台上,上面的代码产生了以下模式,这就是我需要的:
> lines()() # 10
> lines().size(20)() # 20
> circles()() # 15
> circles().size(30)() #30
您可能会注意到,f.size
和g.size
方法是闭包,lines
和circles
上的方法相同。然后我的问题是:如何避免复制size
方法的代码?(使用coffeescript或javascript)
我尝试了不同的解决方案,但我找不到正确的方法。为了复制闭包,size
方法中的size
变量应该引用size
上第一行定义的lines
变量(同样适用于{ {1}})。
答案 0 :(得分:2)
您可以定义工厂函数来生成单独的“构造函数”:
shape = (defaultSize, calculate = (size) -> size) ->
() ->
size = defaultSize
f = () -> calculate size
f.size = (_) ->
size = _
f
f
lines = shape(10)
circles = shape(15, (size) -> size * size * Math.PI)
这编译为:
var circles, lines, shape;
shape = function(defaultSize, calculate) {
if (calculate == null) {
calculate = function(size) {
return size;
};
}
return function() {
var f, size;
size = defaultSize;
f = function() {
return calculate(size);
};
f.size = function(_) {
size = _;
return f;
};
return f;
};
};
lines = shape(10);
circles = shape(15, function(size) {
return size * size * Math.PI;
});
console.log(lines()());
console.log(lines().size(20)());
console.log(circles()());
console.log(circles().size(30)());
答案 1 :(得分:2)
您无法在代码中使用辅助函数,因为它无法按预期访问闭包变量。但是,您可以将整个代码包装在一个函数中,以便它分别返回lines
或circles
函数:
make = (def, accessor) ->
() ->
size = def
f = () -> accessor size
f.size = (_) ->
size = _
f
f
lines = make 10, (size) -> size
circles = make 15, (size) -> size