JavaScript的嵌套函数如何工作?

时间:2015-01-20 14:56:39

标签: javascript

我是JavaScript世界的新手。今天在使用JavaScript时我发现了以下片段:

function sum (a) {  
    var sum = a;

    function f (b) {
        sum += b;

        return f;
    }

    f.toString = function () {
        return sum;
    }

    return f
}

//Calling the function
console.log(sum(4)(5));

你能帮我理解f.toString何时被执行?

2 个答案:

答案 0 :(得分:4)

将对象传递给console.log()时,会调用.toString()以打印出该值。

因此,

sum(4)

返回一个函数。随后调用该函数

sum(4)(5)

也会返回一个函数。然后传递给console.log(),控制台中的结果是

9

应该注意的是console API是一个相当不稳定的准标准,并且因为它被设计为调试辅助,所以有一些行为可能令人困惑。然而,在这种情况下,它似乎只是简单地调用.toString()而没有任何其他“有用”的有趣业务。但是,如果您只是将一个简单的空对象传递给console.log(),就像这样

console.log({})

你得到(至少从Firefox中的Firebug)一个有用的界面来导航对象。如果您正在调试某些内容,那就太棒了,但是如果您正在尝试查看该语言的工作方式,那么这种行为可能会让您感到困惑。

作为最后一点,可以扩展已发布代码中的技巧,以便函数可以通过添加.valueOf()方法来泄露数值结果:

function sum (a) {  
    var sum = a;

    function f (b) {
        sum += b;

        return f;
    }

    f.toString = function () {
        return sum;
    };
    f.valueOf = function() {
        return sum;
    };

    return f;
}

如果你这样做,那么你会从

得到正确的答案
console.log(2 * sum(4)(5))

答案 1 :(得分:3)

执行sum(4)(5)时,首先执行sum(4),返回函数f

此函数可以访问变量sum(由于JavaScript函数的闭包属性[1])。此函数执行求和并再次返回函数f

这一次console.log正在尝试打印函数f,因此我们通过定义f.toString来打印总和,明确定义应该如何打印函数。

编辑:如果您想知道为什么只需添加两个数字就会感到非常痛苦,请尝试以下操作:

add(2)(1)(45)(22)

这是有效的,因为现在递归调用f并且sum被更新,这也是由于闭包属性。

1:即使父函数超出范围,内部函数也可以访问父函数的变量。