[英]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.