为什么我应该考虑在我的代码中使用JavaScript闭包?

3
使用JavaScript闭包的好处是什么?如果我认为通常可以编写更简单直接的代码,为什么还要考虑使用闭包呢?
例如,考虑以下内容:
    function multiplier(factor) {
       return function(number) {
          return number * factor;
       };
    }

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

//////////////////////////////////////////////////////////////////

    function myMultiplier(factor, number) {
         return number * factor;
     }

    console.log(myMultiplier(2, 5)); 

它们都输出10,但我发现我的乘法函数更容易理解、更快写,并且只需要一个函数即可。为什么我应该考虑闭包版本而不是我的版本?

提前感谢。


在这种特定情况下,没有理由。 - Linuxios
https://dev59.com/6XVD5IYBdhLWcg3wBm5h?rq=1 - worldask
1
不需要火焰喷射器来点一支香烟。 - jimm101
想象一下,在t0时你只知道因子,在t1时你只知道数字。这是我现在能想到的唯一用例。 - axelduch
部分函数应用是您考虑使用闭包的原因之一。就像在您的示例中一样。 - akonsu
2
在你的例子中,闭包并不是很有用。闭包允许存在持久变量而不会污染全局命名空间。你可以多次调用一个函数,它会“记住”之前的内容。 - Steve Wellens
3个回答

3

在需要注册事件处理程序的for循环中,你可能需要使用闭包。 for 循环不会创建新的作用域。这意味着,如果在循环内部注册依赖于循环过程中局部变量值的事件处理程序,则需要使用闭包将这些值与处理程序封装起来。

考虑以下两个片段。没有使用闭包的代码将导致意外结果。

没有使用闭包

for(var i = 0; i < locations.length; i++){
    var marker = new google.maps.Marker(...);
    ...
    google.maps.event.addListener(marker, 'click', function(){
        ...
        // At the time of click the for loop has finished.
        // Thus, marker will be the last marker that was created in the loop.
    });
}

使用闭包

for(var i = 0; i < locations.length; i++){
    var marker = new google.maps.Marker(...);
    ...
    google.maps.event.addListener(marker, 'click', (function(marker){
        return function() {
            ...
            // The marker object is wrapped in the closure and
            // will possess the correct value
        }
    })(marker)); // Pass in marker to make the closure work
}

这似乎是一个很好的理由。 - DEdesigns57

2

你提供的代码只是演示了“闭包是什么”,相当于编写“hello world”应用程序。

闭包允许你传递数据和逻辑,这增加了某些代码部分的可重用性:

var arr = [81,55,75,5,3,6,95,0,55,-97];

var sorter = function(modifier) {
    return function(arr){
        arr.sort(modifier);
    };
};

var asc = sorter(function(a,b){
   return a > b; 
});

var desc = sorter(function(a,b){
   return a < b; 
});

asc(arr);
console.log(arr);

desc(arr);
console.log(arr);

这将输出:
[-97, 0, 3, 5, 6, 55, 55, 75, 81, 95]
[95, 81, 75, 55, 55, 6, 5, 3, 0, -97] 

参见:http://jsfiddle.net/jimschubert/7nnycrfj/

编辑:您可以通过添加不同类型的数组来查看可重用性的工作方式:http://jsfiddle.net/jimschubert/7nnycrfj/1/


我总觉得像这样的代码更难理解,但这可能只是因为我刚开始学这些东西... - DEdesigns57
这是属于函数式编程范畴。你可以在这里阅读相关内容:http://eloquentjavascript.net/1st_edition/chapter6.html - Joseph Yaduvanshi

-3

如果你能写出更简单、更直接的解决方案,就用那种方式。可以使用 JavaScript 或其他语言。

有这个功能并不意味着你应该使用它。只有在它符合你的目的时才应该使用它。在这种情况下,你不应该使用闭包,正如你所指出的那样。

但是闭包并不是毫无用处的。它们是许多编程语言的主要特性。你可以查看任何关于它们的文档,了解它们的用途。例如这里。


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