闭包和currying中的引用在js中如何工作?

时间:2018-07-28 04:00:43

标签: javascript ecmascript-6 closures currying

以下程序使我非常困惑,console.log()是我添加的。

function add(a) {
    console.log("1");
    var total = a;
    console.log("2");
    var _fn = function (b) {
        console.log("3");
        total += b;
        console.log("4");
        return _fn;
    };
    console.log("5");
    _fn.toString = _fn.valueOf = function () {
        console.log("6");
        return total;
    };
    console.log("7");
    console.log("_fn: " + _fn);
    return _fn;
}

当我运行add(1)(2)时,控制台显示:

1
2
5
7
6
_fn: 1
3
4
6
ƒ 3

我的问题是:

1)在var _fn =函数(b){...}中,_fn在“ return _fn”语句中指的是什么?如果它指的是自己,那么它不是像这样的无限递归

var _fn = function (b) {
    total += b;
    return function (b) {
        total += b;
        return function (b) {
            total += b;
            return _fn;
            .
            .
            .
        }
    }
}

2)在控制台中,它显示“ _fn:1”,这意味着返回了1,但显然,已返回_fn(该函数),以便继续进行计算。因此,实际返回的_​​fn与控制台中显示的值之间存在冲突。

1 个答案:

答案 0 :(得分:4)

  

在var _fn =函数(b){...}中,_fn在“ return _fn”语句中指的是什么?

return语句表示,当调用此函数时,该函数的返回值将是该函数对象本身(的引用)。请注意,它返回函数对象,不调用它。只是对象,没有电话。至少还没有。...

  

如果它指向自身,那么它不是像这样的无限递归...

否,因为不会立即调用返回值(即函数)。有点像这样:

function g() {return g}
g()

运行不会陷入无限循环。您调用函数g,然后返回g。您可以自己进行g()()()()()()(),但是仍然可以“停止”。递归是函数调用本身而不是返回本身!

  

在控制台中,它显示“ _fn:1”,这意味着返回了1,但显然,已返回_fn(该函数),以便计算可以继续进行。因此,实际返回的_​​fn与控制台中显示的值之间存在冲突。

好吧,说1被归还 可能是不正确的;相反,代码会强制所有console.log(以及类似的对象)产生total的当前值。在您进行console.log时,total具有第一个参数的值,即1。您非常聪明地打印了所有这些数字,因此它应该有助于您的理解。确认打印出7后,您尚未完成添加的后续调用。这就是为什么您看到1.