JavaScript中闭包的具体实际应用场景

4

我已经使用JS两年了,我的Pluralsight评估为我在JS方面熟练掌握,我了解原型继承、高阶函数、IIFEs等,并且在实际情况下使用它们,但是闭包是其中一个概念,你理解了它,但是找不到任何在实际开发中使用它的理由。我的意思是,我知道如果我说:

function expClosure(val){
   //do something to val-->anotherVal
   return function(val){return anotherVal)};
}
var exp = expClosure(val);
exp(); --> returns the value of anotherVal;

我的问题是为什么我要这样做,或者说有哪些具体情况会让我考虑使用它。


应该返回return function(otherVal){return anotherVal)};,因为你使用val覆盖了闭包。现在它是围绕着val的一个闭包。 - Nina Scholz
闭包在回调函数中经常被使用,因此它们可以保留异步函数调用时绑定的变量值。 - Barmar
我猜你真正好奇的是高阶函数,而不是一般的闭包。 - Barmar
在这里添加一个演示jsfiddlehttps://jsfiddle.net/guptaaditya24/2qveyn0w/ - Aditya
这里有一篇相关的帖子链接 - RBT
3个回答

1
我在我的实用学士论文(2.2.2)中写了一点关于这个的内容。
隐藏变量是闭包的一个有价值的用法。与其他一些语言不同,JavaScript中的变量不能声明为私有、公共等。但使用闭包可以隐藏只能在内部使用的变量。例如:
function Car() {
   var speed = 0;

   return {
      accelerate: function() {
         speed++;
      }
   }
}

var car = new Car();
car.accelerate();

speed 可以通过闭包被 accelerate 访问,但除此之外完全无法访问。


1
闭包的主要好处是可以使用闭包“部分应用”函数,然后传递部分应用的函数,而不需要传递未应用的函数和任何需要调用它的数据(在许多情况下非常有用)。
假设您有一个函数f,将来需要2个数据才能操作。一种方法是在调用时将两个数据作为参数传递。这种方法的问题是,如果第一个数据立即可用,而第二个数据不可用,则必须将其与f一起传递,以便在调用函数时它在范围内。
另一个选择是立即将可用数据提供给函数。您可以在数据上创建闭包,让函数引用外部数据,然后仅传递函数本身。
选项2要简单得多。
你还可以使用闭包在不支持静态变量的语言中实现函数中的静态变量。Clojure(这种语言)通过返回传递函数的修改版本来实现其memoize函数,该函数保留对表示参数/返回值对的映射的引用。在运行函数之前,它首先检查是否在映射中已经存在参数。如果存在,则返回缓存的返回值,而不是重新计算它。(改编自我对另一个问题的回答)

0

由于这个问题并不需要编程答案,我会添加一个回答而不是评论。你在问题中引用的例子,我同意是一个闭包,并且我相信你通过使用 pluralsight 讲座已经很好地理解了闭包。因此,上述例子并不是闭包的唯一用例。闭包是记住它们被创建的作用域的函数。

这其中一个明显的例子是 jQuery 中每个人都使用的回调注册机制。闭包无处不在,我们许多人一直在无意中编写闭包。

因此,如果你使用过 redux,你就会知道整个概念基于闭包,即封装数据(称为应用程序状态)。闭包提供了面向对象支持语言中使用的私有变量的概念。

我在下面添加另一个闭包的例子,这样你可能能够更好地理解。

function processOrder(amount){
  var temp_order_id = +new Date() + 'USERID';
  var afterPaymentCompleteOrder = function(status){//callback
  //afterPaymentCompleteOrder is a closure as it remembers the scope in which it is created when it is being called. So when ivoked it remembers the value of temp_order_id
     if(status){
          complete_order_method(temp_order_id);
     }
     else
          delete_order_details(temp_order_id);
  }

  start_payment_process(amount, afterPaymentCompleteOrder);
}

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