为什么关闭很重要?

时间:2014-07-23 19:59:19

标签: closures

封闭与类的优点是什么,为什么封闭有优势?类具有对这些数据进行操作的数据和行为/方法。如果有人能回答我这个问题?我来自OOP背景,我没有看到这种范例"代码作为数据"非常明了。它在功能语言中的构成是否重要?

感谢。

2 个答案:

答案 0 :(得分:1)

它的主要优点是它可以通过引入全局变量等来创建私有作用域并避免影响闭包之外的代码。 这是在JavaScript中使用的一种非常常见的模式。

答案 1 :(得分:0)

您可以将变量放在一个类中(无论如何都是多种语言),但是该类上的函数共享完全相同的变量集。您还可以创建一个对象来保存变量并在对象上定义函数,然后创建主要的"事物"感兴趣的是对象,而你可能不关心变量(除非你第一次初始化它们),只关心函数。

让我们假设你想在运行时创建基本上相同但具有不同变量的函数(例如,每个函数都会吐出函数的下一个值,当函数被赋予它时被定义为)。您不能使用类变量和类函数(方法)来实现它,因为类变量是共享的(即,您只有一个函数,并且它一次只能处理一个集合)。

您可以创建一个包含初始值(即集合)的对象,并在引用这些值的对象上定义一个函数。如果你真正想要的是一个函数,那么这个对象可能看起来不自然:毕竟,你带着一个对象来保存你的集合,指向下一个要发出的元素,以及发出它的功能,而你只需要一个功能。

闭包是创建这种功能的自然方式。在创建闭包时,它会获得一组私有变量,这些变量在函数调用之间保留其值,但这些变量(引用环境)是隐藏的。如果你试图用一个对象实现同样的东西,那么你要首先处理对象,然后再处理你的函数,即使它是""您感兴趣的是功能(一旦您初始化了这些变量,您就不会关心它们。)


这是一个用例:回调。

假设您希望在许多地方多次使用相同的回调函数,但您希望不仅使用事件对象调用它,还要调用一些数据以在设置时指定。例如,假设您的函数被调用myFunc(event),并且当它被调用时,您希望它记录您传递的字符串,因此您确实希望将其定义为myFunc(event, string_to_be_logged),如下所示:

function myFunc(event, string_to_be_logged) {
  ...do stuff...
  log(string_to_be_logged);
}

调用回调的框架需要一个函数而不需要其他任何东西,只用事件对象调用它。如果您只执行一次或两次,则可以定义两个版本的回调:

function myFuncABC(event) {
  ...do stuff...
  log("ABC");
}

doSomethingAsyc(&myFuncABC);   // pass the pointer to the callback function

function myFuncDEF(event) {
  ...do stuff...
  log("DEF");
}

doSomethingAsyc(&myFuncDEF);

但你可以看到这个问题!

相反,我们可以动态创建回调函数,作为闭包:

function createCallback(str) {
  var myFunc = function(event) {
                 ...do stuff... 
                 log(str);
               }
  return myFunc;
}

我们生成的函数是一个闭包,因为它保留了它的引用环境:str变量。我们以这种方式生成的每个回调函数都有自己的str私有副本。

现在,我们可以执行以下操作:

var mf1 = createCallback("ABC");
doSomethingAsyc(myFunc);    // pass the variable containing the callback function
var mf2 = createCallback("DEF");
doSomethingAsync(mf1);

并且第一个回调将记录" ABC"而第二个记录" DEF"。