首页 > 解决方案 > 在 ColdFusion 中,我可以按值捕获封闭变量吗?

问题描述

假设我们正在构建一个闭包列表,这些闭包对一个值执行某些功能,i其中i每次迭代都是一个新值。例如:

function foo() {
    var result = [];
    for (var i = 0; i < 4; i++) {
        arrayAppend(result, function() { return i; });
    }
    return result;
}

flist = foo();
newline = "<br>";
for (f in flist) {
    WriteOutput(f() & newline);
}

看来 CF 是i通过引用捕获的——上面的结果是:

4
4
4
4

这些结果在 CF2011、CF2016、Lucee4.5 和 Lucee5 中是相同的(我通过 trycf.com 进行了测试,很方便,假设它确实在运行这些引擎)。

我已经实现了一种我称之为 a 的迂回方式value_capturing_closure,但并不想把它强加给我的团队,因为最好坚持使用每个人都熟悉的 CF 习语。是否可以在 CF 中使用原生 CF 闭包语法按值捕获变量?

标签: coldfusionclosures

解决方案


这就是闭包的工作原理。您需要做的是导致值的副本发生,并将该副本绑定到未持久化的函数。这可以通过创建一个接受参数的函数然后创建一个函数来完成。

function foo() {
    var result = [];
    for (var i = 0; i < 4; i++) {
        arrayAppend(result, function(x) {   
            return function(){ return x };
        }(i));
    }
    return result;
}

或为了清楚起见而分离成一个单独的功能

function foo() {
    var result = [];
    for (var i = 0; i < 4; i++) {
        arrayAppend(result, createClosure(i));
    }
    return result;
}


function createClosure(x) {
    return function() {
        return x;
    }
}

推荐阅读