了解递归函数的蹦床优化

时间:2016-02-10 12:41:36

标签: javascript recursion functional-programming

我有以下蹦床实施:

function trampoline(f) {
    while (f && f instanceof Function) {

        f = f.apply(f.context, f.args);

    }
    return f;
}

它同样有用,例如是阶乘:

function factorial(n) {
    function recur(n, acc) {
        if (n == 0) {
            return acc;
        } else {
            return recur.bind(null, n-1, n*acc);
        }
    }
    return trampoline(recur.bind(null, n, 1));
}

问题在于我不明白f.contextf.args如何作为参数传递,这些属性在蹦床内的复发函数中显然无法找到,当我,例如,尝试访问和console.log他们。然后它会记录undefined个值。

传递函数参数的这个特定实现的机制是什么?

1 个答案:

答案 0 :(得分:2)

正如您所看到的here,函数对象没有名为argscontext的属性,这就是它们在控制台中显示为undefined的原因登录。在函数本身内部,您可以在argumentsthis对象中访问这些值,但在绑定函数(或未绑定函数)中它们在外部中不可见。< / p>

您的代码工作原因是因为如果函数与参数绑定,则会附加apply个参数。当您bind函数时,您只能绑定上下文(this)或上下文和参数。如果绑定上下文和参数,当您applycall该函数时,您传入的参数将附加在参数列表的末尾。在你的特殊情况下,你正在......

f = f.apply(undefined, undefined);

... f的结果参数为:

[...parametersWhenTheFunctionWasBound, undefined, undefined]