简体   繁体   English

闭包和CoffeeScript的作用域

[英]Closures and CoffeeScript's Scoping

The following code defines two functions, lines and circles , that return a function, f and g respectively. 以下代码定义了两个函数, linescircles ,分别返回函数fg Functions f and g are equal ( () -> size ) only for simplicity, but in general they are different functions of the variable size . 函数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

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 . 正如您可能注意到,在f.sizeg.size方法是关闭和他们两个相同的linescircles Then my question is: how I can avoid to duplicate the code for the size method? 然后我的问题是: 如何避免重复size方法的代码? (with coffeescript or javascript) (使用coffeescript或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 ). 以复制的关闭,该size内侧可变size的方法应该是指size在所述第一行上定义的变量lines (以及同样适用于circles )。

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

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: 但是,您可以将整个代码包装在一个函数中,以使其分别返回linescircles函数:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM