将库转换为JavaScript闭包

时间:2015-12-25 03:01:29

标签: javascript google-apps-script closures

我有一个JavaScript函数的外部库,我需要将其引入我的服务器端Google Apps脚本项目。我这样做主要是出于性能原因,还因为Google now recommends against using external libs

在当前配置中,外部库中的函数由<Libname>.funcName()引用,并且同样包含库中的任何全局变量,例如: <Libname>.globA。如果我只是将库复制到项目中的文件中,那些函数(和“全局”)将仅被引用为funcName()。我的项目中有数百个此类引用可能需要更改。没关系;这是一个全球性的搜索和替换可以解决。但是,我担心“命名空间”问题...由于库是第三方代码,我无法控制它,现在我遇到名称冲突,因为库中的对象和函数具有与我的一些代码相同。

如何将此代码以一种将其内部详细信息与我的代码分开的方式提取到我的项目中?有没有办法做到这一点并保留当前的命名约定<Libname>.funcName()?我相信JavaScript闭包是正确的解决方案,但对它们知之甚少。

我的项目Code.gs

var globA = { key: 'aKey', value: 'valA' };

function myFunction() {
  var a = MyLib.getValue();
  Logger.log( JSON.stringify( a ) );  // { key: 'libKey', value: 'valLibA' };
}

function getValue() {
  return globA;
}

库“MyLib”,Code.gs

var globA = { key: 'libKey', value: 'valLibA' };

function getValue(  ) {
  return globA;  
}

3 个答案:

答案 0 :(得分:2)

有两种方法可以解决这个问题。

您可以使用browserify将节点库转换为一段代码,只需将其粘贴到应用程序脚本编辑器中即可。

或者您使用immediately invoked function expression自行包装代码。

像这样:

var MyLib = (function() {
  var globA = { key: 'libKey', value: 'valLibA' };
  function getValue(  ) {
    return globA;  
  }

  return {
    globA: globA,
    getValue: getValue
  }
})();

顺便说一句。如果你创建了几个.gs文件,它们中的代码/定义将按照编辑器左侧显示文件名的顺序执行。

答案 1 :(得分:0)

在我看来,使用异步模块定义(AMD)来构建模块同时保持某种程度的关闭的最佳方法。一个好的库就是requirejs。

您将定义并要求您的模块如下:

define(['path/to/your1stLib', 'path/to/your2ndLib', ...], function(Your1stLib, Your2ndLib, ...) {

  var MyOtherLib = {
    Your1stLib.doStuff(...)

    // rest of the code
  }

  return MyOtherLib;

});

答案 2 :(得分:0)

我建议将库包装为AMD模块,并使用requirejs或类似的方法来加载依赖项。