Closures and CoffeeScript's Scoping

三世轮回 提交于 2019-12-12 01:53:03

问题


The following code defines two functions, lines and circles, that return a function, f and g respectively. Functions f and g are equal (() -> size) only for simplicity, but in general they are different functions of the variable 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

On the console, the above code results on the following pattern, which is what I need:

> lines()() # 10
> lines().size(20)() # 20
> circles()() # 15
> circles().size(30)() #30

As you may note, the f.size and g.size methods are closures and they are the same on both lines and circles. Then my question is: how I can avoid to duplicate the code for the size method? (with coffeescript or javascript)

I tried different solutions, but I did not find the right way. In order to replicate the closure, the size variable inside the size method should refer to the size variable defined at the first line on lines (and the same holds for circles).


回答1:


You can't use a helper function in your code, as that won't have access to the closure variable as expected. However, you can wrap your whole code in a function so that it returns you the lines or circles function respectively:

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

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



回答2:


You can define a factory function to produce your individual "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)

This compiles to:

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)());


来源:https://stackoverflow.com/questions/28670514/closures-and-coffeescripts-scoping

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!