Groovy && JavaScript 闭包

Groovy && JavaScript 闭包

http://my.oschina.net/xinxingegeya/blog/403391

这篇文章写了JavaScript的闭包,在这里用Groovy 代码来实现JavaScript中的闭包。


示例一

JavaScript代码,

var global = 1;
function outer() {//函数作用域
    var outer_local = 2;
 
    function inner() {//一个内部函数inner()has access to all variables
        var inner_local = 3;
        return inner_local + outer_local + global;
    }
 
    return inner();
}
 
console.log(outer());//6

下面是groovy代码实现,你可能首先会这么写,

closures_app6.groovy

def str1 = "hello "

def f1() {
    def str2 = "world "
    def inner_closure = {
        def str3 = "!"
        str1 + str2 + str3;
    }
}

println f1().call()

在方法f1 中 定义了一个闭包inner_closure ,这个闭包没有绑定任何变量,包含自由变量 str2,str3。运行并输出,

Caught: groovy.lang.MissingPropertyException: No such property: str1 for class: com.usoft.closures_app6

groovy.lang.MissingPropertyException: No such property: str1 for class: com.usoft.closures_app6

at com.usoft.closures_app6$_f1_closure1.doCall(closures_app6.groovy:20)

at com.usoft.closures_app6$_f1_closure1.doCall(closures_app6.groovy)

at com.usoft.closures_app6.run(closures_app6.groovy:24)

看来是不能这样写,改成下面这样,

def str1 = "hello "

def f1() {
    def str2 = "world "
    def inner_closure = { arg ->
        def str3 = "!"
        arg + str2 + str3;
    }
}

println f1().call(str1)


示例二

js代码,

var a = "global variable";
var F = function () {
    var b = "local variable";
    var N = function () {
        //The function N has access to its private space, to the F() function's space, and to the global space.
        var c = "inner local";
        return b;
    };
    return N;
};

var inner = F();
var b = inner();
console.log(b);//local variable

使用groovy实现,

def str1 = "hello "

def f1() {
    def str2 = "world "
    def inner_closure = {
        str2
    }
}

println f1().call() // world

通过groovy闭包,打破了 str2 变量的方法作用域。


示例三

js代码,

function F(param) {
    var N = function () {
        return param;
    };
    param++;
    return N;
}
 
var inner = F(123);
var result = inner();
console.log(result);

groovy代码,

def f(arg) {
    def inner_closure = {
        arg
    }
}

println f("hello world!").call()

通过闭包可以拿到 方法运行时的参数,打破了方法参数的作用域。


示例四

js代码,

function F() {
    var arr = [], i;
    for (i = 0; i < 3; i++) {
        arr[i] = (function (x) {
            return function () {
                return x;
            };
        }(i));
    }
    return arr;
}
 
var arr = F();
console.log(arr[0]());//0
console.log(arr[1]());//1
console.log(arr[2]());//2

groovy的闭包实现,

先来写一个错误的实现,如下,

def f() {
    def arr = []
    for (i in 0..<4) {
        arr[i] = {
            i
        }
    }
    return arr
}

def arr = f()
println arr[0].call()
println arr[1].call()
println arr[2].call()
println arr[3].call()

运行并输出,

3

3

3

3

可以看到,这个闭包没有绑定到当前的循环变量上,当执行闭包时,其实绑定的变量是最后一个循环变量。那如何绑定当前的循环变量,如下groovy闭包代码,

def f() {
    def arr = []
    for (i in 0..<4) {
        // 让闭包保持当前的上下文环境
        arr[i] = { arg ->
            def loop_closure = {
                arg
            }
        }.call(i)
    }
    return arr
}

def arr = f()
println arr[0].call()
println arr[1].call()
println arr[2].call()
println arr[3].call()


示例五

js代码,可以实现 iterator 功能

function setup(x) {
    var i = 0;
    return function () {
        return x[i++];
    };
}
 
var next = setup(['a', 'b', 'c']);
console.log(next());//a
console.log(next());//b
console.log(next());//c

groovy代码,

def setup(args) {
    def i = 0
    inner_closure = {
        args[i++]
    }
}

def next = setup(['a', 'b', 'c'])
println next.call()
println next.call()
println next.call()

next 这个闭包,保持了运行时环境。

下面是直接返回一个匿名的闭包(匿名的代码块)

def setup(args) {
    def i = 0
    return {
        args[i++]
    }
}

def next = setup(['a', 'b', 'c'])
println next.call()
println next.call()
println next.call()

通过JavaScript 和 Groovy 闭包的对比,闭包都是大同小异的。

=================END=================

你可能感兴趣的:(Groovy && JavaScript 闭包)