多个文件上的相同函数闭包

Same function closure over multiple files

本文关键字:函数 闭包 文件      更新时间:2023-09-26

我有一个庞大的函数,我想把它分解成多个文件。下面是我的函数的结构:

var myFunction = function (argument) {
   var private1, private2, private3;
   var gadget1 = (function () {
       // Play around with private1, private2, private3, argument
       return gadget1API;
   }());
   var gadget2 = (function () {
       // Play around with private1, private2, private3, argument
       return gadget2API;
   }());
   var gadget3 = (function () {
       // Play around with private1, private2, private3, argument
       return gadget3API;
   }());
   return myFunctionAPI;
}

在这里,为gadget设置命名空间以将它们分散到多个文件中是行不通的,因为它们都依赖于myFunction闭包中的private1, private2, private3。为此,我需要myFunction闭包来关闭3个不同的文件。

您应该将其创建为对象,而不是闭包,并首先加载它,如下所示:

function myObject(argument) {
   this.arg = argument;
   this.private1 = whatever;
   this.private2 = whatever;
   this.private3 = whatever;
   this.gadget1 = (function () {
   // Play around with this.private1, this.private2, this.private3, this.arg
       return gadget1API;
   }());
   this.gadget2 = (function () {
   // Play around with this.private1, this.private2, this.private3, this.arg
       return gadget2API;
   }());
   this.gadget3 = (function () {
   // Play around with this.private1, this.private2, this.private3, this.arg
       // return gadget3API; i don't see what this is for, so commented out
   }());
   return myFunctionAPI;
}

并在你定义它之后实例化它

var myFunction = new myObject(theargument);

你可以像这样访问它的函数:

var something1 = myFunction.gadget3();

答案很简单:不可能。

您所追求的似乎是一个成熟的参数化模块系统。如果在JavaScript/ECMAScript的未来版本中不包含该功能,那么通过在每个单独的小工具文件中对显式闭包环境进行参数化,然后通过实例化小工具将所有内容绑定在一起(即链接小工具),从而手动模拟上述闭包行为可能就足够了。

gadget1.js:

var gadget1 = function (env) {
   with (env) {
   // Play around with private1, private2, private3, argument
   return gadget1API;
   }
}

gadget2.js:

var gadget2 = function (env) {
   with (env) {
   // Play around with private1, private2, private3, argument
   return gadget2API;
   }
}

main.js:

var myFunction = function (argument) {
  var private1, private2, private3;
  var gadgetFns = [gadget1, gadget2, …];
  var gadgets = [];
  function closureEnvF() { this.argument=argument, this.private1=private1, this.private2=private2, this.private3=private3 };
  var closureEnv = new closureEnvF();
  for (var i = 0; i<gadgets.length; i++) {
     gadgets[i] = gadgetFns[i].apply(null, closureEnv);
  }
  return myFunctionAPI; 
}

这可能可以简化,取决于闭包环境中的所有元素是否都是从对象开始的。这是一个相当好的解决方法,但它确实说明了闭包并不神奇(仅仅是一个函数加上一个隐式传递的闭包环境)。