有人能向我解释一下这个JavaScript函数的流程吗?(闭包概念)

5
我正在阅读《JavaScript 高级程序设计》。第三章介绍了 "闭包" 的概念,并提供了几个示例之一如下:
function multiplier(factor) {
    return function(number) {
        return number * factor;
    };
}

var twice = multiplier(2);
console.log(twice(5));
// → 10

我觉得我理解了这个概念。如果我首先执行console.log(twice),由于变量number未定义,我得到的是[Function]。我不明白的是twice(5)如何工作。为什么本地变量number被初始化为值5
另外,为什么如果我执行console.log(multiplier(2,5)),我没有得到10作为结果?
谢谢。

@旁注:谢谢! - Noob_Number_1
这是一个柯里化函数。 - user6445533
3个回答

11

multiplier返回一个函数,因此twice等于返回的函数,而不是multiplier函数。

然而,当调用multiplier时,将传递并在返回的函数中使用factor变量。

为了更容易理解,可以认为twice基本上是:

var twice = function(number) {
    return number * 2;
};

当你调用 multiplier(2) 时,函数中的 factor 已经被替换为你传入的值。


当你使用 console.log(twice) 时,实际上并没有调用函数 twice,而是记录了它的值。所以输出 [Function] 并不是因为 number 是未定义的,而是因为你输出的是函数本身而不是结果。


在这里,你通过提供两个参数来调用 multiplier,尽管你只定义了函数接受一个参数 (factor)。在 JavaScript 中,这不会导致错误,但你只会得到映射在 factor 中的第一个值 (factor = 2)。

注意:即使没有为参数定义参数,仍然有办法访问所有提供的参数( 这里有个例子)。

以下代码可能会得到一个结果为10 的可能性,这可能会很有趣:

var result = multiplier(2)(5); // result = 10

1
好的,现在我明白了。我也明白为什么multiplier(2,5)不能返回10。谢谢伙计! - Noob_Number_1
factor 没有传递给匿名函数。它在函数内部是可访问的,因为它是一个自由变量,而匿名函数是一个闭包。这种区别很重要,因为自由变量存储在堆上,而不是栈上。 - user6445533
@LUH3417:我是说当调用multiplier函数时,因子变量被传递。我并没有说它被传递到匿名函数中。我只是说它被返回的函数(匿名)所使用。我认为你的评论已经足够解释我的陈述被你误解的情况了。 - musefan

2

Multiplier是一个函数,它返回一个匿名函数,该函数接受一个参数(数字)。

var twice = multiplier(2);

基本上是:
 var twice = function(number) {
        return number * 2;
    };

1
如果您执行 < /p>。
console.log(multiplier(2,5))

你调用函数时传入了两个参数,然而

function multiplier(factor) {}

只需要一个参数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接