闭包和 CoffeeScript 的作用域
Closures and CoffeeScript's Scoping
下面的代码定义了两个函数,lines
和circles
,即return一个函数,分别是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
变量应该引用 lines
第一行定义的 size
变量(同样适用于 circles
).
你可以定义一个工厂函数来生产你的个人 "constructors":
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)());
您不能在您的代码中使用辅助函数,因为它无法按预期访问闭包变量。但是,您可以将整个代码包装在一个函数中,以便它 returns 分别是 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
下面的代码定义了两个函数,lines
和circles
,即return一个函数,分别是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
变量应该引用 lines
第一行定义的 size
变量(同样适用于 circles
).
你可以定义一个工厂函数来生产你的个人 "constructors":
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)());
您不能在您的代码中使用辅助函数,因为它无法按预期访问闭包变量。但是,您可以将整个代码包装在一个函数中,以便它 returns 分别是 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