【问题标题】:Closures and CoffeeScript's Scoping闭包和 CoffeeScript 的作用域
【发布时间】:2015-02-23 17:59:42
【问题描述】:

以下代码定义了两个函数linescircles,它们分别返回一个函数fg。函数fg 相等(() -> 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.sizeg.size 方法是闭包,它们在 linescircles 上是相同的。那么我的问题是:如何避免重复 size 方法的代码?(使用咖啡脚本或 javascript)

我尝试了不同的解决方案,但我没有找到正确的方法。为了复制闭包,size 方法中的size 变量应该引用在lines 的第一行定义的size 变量(circles 也是如此)。

【问题讨论】:

  • 你不能;私有构造函数变量的方法闭包必须发生在构造函数中。如果你将_size公开,你可以使用原型方法来达到它。

标签: javascript coffeescript


【解决方案1】:

您不能在代码中使用辅助函数,因为它无法按预期访问闭包变量。但是,您可以将整个代码包装在一个函数中,以便它分别返回 linescircles 函数:

make = (def, accessor) ->
    () ->
        size = def
        f = () -> accessor size
        f.size = (_) ->
           size = _
           f
        f

lines = make 10, (size) -> size
circles = make 15, (size) -> size

【讨论】:

  • 这就是我要找的。谢谢。
【解决方案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)());

【讨论】:

  • linescircles 应该是“构造函数”,它们的每个调用都应该创建自己的size
  • 他,现在你的解决方案看起来和我的一样 :-) +1
猜你喜欢
  • 2017-06-18
  • 2010-10-12
  • 1970-01-01
  • 2011-01-19
  • 2014-02-13
  • 2013-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-14
相关资源
最近更新 更多