JS文件之间的多个范围

时间:2017-07-03 20:17:43

标签: javascript module scope global

This answer展示了如何跨多个JS文件共享范围。

但我想知道如何在多个文件之间共享两个(或更多)更广泛的范围。

试验,我发现对上述答案的轻微调整涉及在文件之间共享一个对象,然后在第一次发现它是一个像这样的空对象时启动它:

var MODULE = (function( widerScopeVariables )
{
    if( $.isEmptyObject( widerScopeVariables ) ){
        // projectWide:
        widerScopeVariables[ 0 ] = {};
        // formsWide:
        widerScopeVariables[ 1 ] = {};
    }
    const projectWide = widerScopeVariables[ 0 ];
    ...

...但问题是projectWideformsWide(意图是更受限制的范围)随后都可用于共享此MODULE变量的每个文件,即使是约定限制使用不打算访问formsWide变量的文件。

此外,每个可能首先加载的文件都必须包含上述代码。

有没有更好的方法在JS中实现这种多级多文件作用域?

1 个答案:

答案 0 :(得分:0)

我找到了一种方法来帮助实现这一目标。它不优雅,只是鼓励正确使用......它不会让JS纯粹主义者满意,但它对我有用。

为避免疑问,我知道JS只有两个范围:全局和功能。

我所做的是将一堆文件放在名为" generic_elements"的子目录中。使用我引用的答案中的设计模式,然后在这些文件中使用:

var HOLDER = (function( holderState )
{
  const genericDir = getDir( -2 );
  const genericWide = holderState[ genericDir ] = holderState[ genericDir ] || {};
  ...
  return holderState;
}( HOLDER || {} ));

其中getDir看起来像这样(全局函数):

function getDir( pathElement ){
    let info = new Error().stack;
    const infoLines = info.replace( /\n/g, ' ' ).split( ' ' );
    const delimiter = '/';
    // [0] or [1] would return the line for this file, not the calling file
    const tokens = infoLines[ 2 ].split(delimiter);
    // get a directory in this path. -2 means penultimate token = string between penultimate and last '/'
    return tokens.slice( pathElement )[ 0 ];
}

......它不是"完全"版本,因为它只返回最终目录而不是主URL目录中的完整路径。

这个想法非常简单:子目录中的一堆文件使用包含这些"文件的子目录的路径"作为holderState对象中的键。他们共享对象genericWide。更高层的模块仍然可以查看这个HOLDER对象,但编码器(希望)同意不使用他们一无所知的模块中的键值对。相反,子目录中的文件能够计算出祖先目录的路径,用-3或-4或其他任何方式调用getDir ......这样他们就可以访问他们的祖先模块' "目录全"对象。