繁体   English   中英

Node.js中的仅模块作用域

[英]Module-only scope in Node.js

我正在尝试获得一个在模块的顶级范围内设置变量的函数,但不会使其泄漏到全局范围内(因为...很糟糕)。 起初,我认为模块中的隐式变量声明会保留在模块中,但似乎脚本调用模块也是如此。

以(aModule.node.js)为例:

var
  onlyToThisModule = true;

function createAGlobal() {
  //creates a implicit var unfortunately
  globalToEveryone = true;
}

createAGlobal(); //this will now appear in the global scope for the script that require() it. eeek.

console.log(onlyToThisModule);

exports = createAGlobal;

然后要求它:

var
  aModule = require('./aModule.node.js');

console.log(globalToEveryone); //outputs "true"
console.log(typeof onlyToThisModule); //outputs "undefined"

我想做的是在createAGlobal中声明一个不会泄漏到全局范围内的变量。 我想将其保留在调用它的函数的范围内。 我知道我可以将其放在模块本身的var语句中,但是我希望仅在有人执行函数时声明变量。 有没有办法实现这种范围界定?

在不使用var情况下定义变量时,该变量将置于全局范围内,并且在此注释的范围之外还有其他细微差别。 它不是“隐式变量”。

无论如何,可以通过require()从任何地方访问模块本身,因此您无需全局设置任何内容:

在一个模块中

exports.globalToEveryone = true;

在另一个模块中

var globalVal = require('aModule').globalToEveryone;

扩展:要控制从任何地方访问的值,几乎可以肯定是全局的。 为了您的目的,一个更好的答案可能是使用访问器方法:

var globalToEveryone = undefined;
exports.globalToEveryone() = function() {
    if (globalToEveryone !== undefined) {
        return globalToEveryone;
    } else {
        // what happens if it hasn't been set yet?
    }
}

对代码感兴趣的其他地方,可以使用

var localVersion = require('aModule').globalToEveryone();

您会发现,尽管必须多输入一些内容才能获得该值,但是您将拥有更多可维护的代码。

为什么要求只有在有人调用函数时才声明变量? 如果不是严格要求,则可以在模块范围内声明它,并在函数范围内对其进行初始化:

var onlyToThisModule; // currently `undefined`

function initVar() {
    onlyToThisModule = true;
}

console.log(onlyToThisModule); // undefined
initVar();
console.log(onlyToThisModule); // true

...另一方面,如果您真的只想在函数中声明一个变量,但又希望模块的其余部分可以使用它,则可以将其创建为类属性:

function myClass() {
    this.onlyToThisModule = true;
}

var mc = new myClass();
console.log(mc.onlyToThisModule);

...但这仍然会通过函数的中介将变量暴露给调用模块。

如果这些都不适合您的情况,那么您将必须提供更多详细信息。

好的。 感谢您的回答尝试,但是经过大量的烦恼和研究, 我认为不可能完全做到我想做的事情,但是我对我的项目已经足够了解了。

死胡同:我能够使用V8的堆栈跟踪并伪造错误来访问作用域链中变量的内容。 不过,我无法写出整个范围。 再加上有点疯狂。 我还尝试了一些Object.defineProperty ,但我从来没有完全按照需要工作。

出于我的目的,它可以将所有内容放入一个对象中,然后使用该对象with其邪恶性要比全局对象小。 对于我需要的情况,它工作正常。 因此,像这样:

var local = { 
    a : '1',
    b : '2',
    c : '3'
};

function contained() {
    with (local) {
        console.log(a,b,c);
    }
}
console.log(typeof a) //undefined
contained();

现在,我只是通过模块的本地对象,并有脚本或其他模块使用with需要的地方。 在语法上没有我想要的那么纯净。 我还认为,隐式变量应该仅在模块本地,因为您可以使用global.foo访问全局变量(我知道,不会发生,这会破坏互联网等)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM