在 Node.js 中,有没有办法从所需模块访问父级的变量范围?
In Node.js is there a way to access the variable scope of the parent from a required module?
对于我的项目,我有很多函数对单个全局变量进行更改,但由于文件很大,我想将这些函数拆分到不同的模块中。但是,在传递全局变量时,它会创建另一个实例。有办法防止这种情况吗?
例如,这是所需的输出:
var global_var=1;
function first_function(){
console.log(++global_var);
}
function second_function(){
console.log(++global_var);
}
first_function(); //outputs 2
second_function(); //outputs 3
first_function(); //outputs 4
但是当试图将 first_function 和 second_function 分成不同的模块时,
//in main.js file
var global_var=1;
var first_function=require(./first_function)(global_var);
var second_function=require(./second_function)(global_var);
first_function(); //outputs 2
second_function(); //outputs 2
first_function(); //outputs 2
//in first_function.js and second_function.js
module.exports=function(global_var){
return ++global_var;
}
我不想每次调用函数时都重新分配或重新传输 global_var,因为更改 global_var 的函数调用每分钟进行数千次 [= =37=] 是一个拥有超过 1000 个键的对象。
有没有办法确保子模块修改全局对象的同一个实例而不传递它?
如果你在没有声明变量的情况下 var
它会被任何模块看到,但这是一个不好的做法,因为这个变量也会影响所有模块:
global_var=1;
var first_function=require(./first_function);
var second_function=require(./second_function);
first_function(); //outputs 2
second_function(); //outputs 3
first_function(); //outputs 4
//in first_function.js and second_function.js
module.exports=function(){
return ++global_var;
}
如果该代码(在我猜测的示例中进行了简化)按照您所说的进行操作,我会感到非常惊讶。这个:
var first_function=require(./first_function)(global_var);
将 global_var
(顺便说一句,它不是全局的,因为它是用 var
定义的)传递给导出的函数。导出函数 returns 该值加一。所以当你调用它时:
first_function();
你实际上应该得到一个数字不是函数的错误。
有很多方法可以解决这个问题。由于您的变量是一个对象,因此无论在何处使用它,都可以通过 reference 获得,这意味着更新一个实例应该更新所有实例。
解决方案 1:使 first_function.js 导出一个函数,该函数 returns 一个函数。
//in first_function.js and second_function.js
module.exports=function(global_var){
// This function will be the value of "first_function"
// when you require it and pass in "global_var"
return function() {
return ++global_var;
};
};
解决方案 2:使用 实际 全局变量。
global.someVar = 1;
// first_function.js
module.exports = function() {
return ++global.someVar;
};
这里需要注意的是,全局变量通常被认为是代码异味(不好的做法)。
解决方案 3:将变量设为文件的导出。再次通过引用缓存导出,因此需要该变量的每个文件都将获得相同的引用。
// global_var.js
exports.global_var = 1;
// first_function.js
var glob = require('./global_var');
module.exports = function() {
return ++glob.global_var;
};
正如 vanadium23 所提到的,这可以使用全局变量来完成。 虽然这是一个非常糟糕的主意。默认情况下,模块模式旨在将代码包含在模块中,并使某些部分可通过导出访问。
解决这个问题的一种方法是传递一个非基元(基本上是一个对象)。正如您提到的,原始类型将作为副本传递,而不是引用。传递对象将确保所需的模块可以更改其字段。
增量-value.js:
module.exports = function(object) { object.value++; };
main.js:
var myObject = { value: 0 };
var incrementValue = require('./increment-value');
incrementValue(myObject);
console.log(myObject); // { value: 1 }
对于我的项目,我有很多函数对单个全局变量进行更改,但由于文件很大,我想将这些函数拆分到不同的模块中。但是,在传递全局变量时,它会创建另一个实例。有办法防止这种情况吗?
例如,这是所需的输出:
var global_var=1;
function first_function(){
console.log(++global_var);
}
function second_function(){
console.log(++global_var);
}
first_function(); //outputs 2
second_function(); //outputs 3
first_function(); //outputs 4
但是当试图将 first_function 和 second_function 分成不同的模块时,
//in main.js file
var global_var=1;
var first_function=require(./first_function)(global_var);
var second_function=require(./second_function)(global_var);
first_function(); //outputs 2
second_function(); //outputs 2
first_function(); //outputs 2
//in first_function.js and second_function.js
module.exports=function(global_var){
return ++global_var;
}
我不想每次调用函数时都重新分配或重新传输 global_var,因为更改 global_var 的函数调用每分钟进行数千次 [= =37=] 是一个拥有超过 1000 个键的对象。
有没有办法确保子模块修改全局对象的同一个实例而不传递它?
如果你在没有声明变量的情况下 var
它会被任何模块看到,但这是一个不好的做法,因为这个变量也会影响所有模块:
global_var=1;
var first_function=require(./first_function);
var second_function=require(./second_function);
first_function(); //outputs 2
second_function(); //outputs 3
first_function(); //outputs 4
//in first_function.js and second_function.js
module.exports=function(){
return ++global_var;
}
如果该代码(在我猜测的示例中进行了简化)按照您所说的进行操作,我会感到非常惊讶。这个:
var first_function=require(./first_function)(global_var);
将 global_var
(顺便说一句,它不是全局的,因为它是用 var
定义的)传递给导出的函数。导出函数 returns 该值加一。所以当你调用它时:
first_function();
你实际上应该得到一个数字不是函数的错误。
有很多方法可以解决这个问题。由于您的变量是一个对象,因此无论在何处使用它,都可以通过 reference 获得,这意味着更新一个实例应该更新所有实例。
解决方案 1:使 first_function.js 导出一个函数,该函数 returns 一个函数。
//in first_function.js and second_function.js
module.exports=function(global_var){
// This function will be the value of "first_function"
// when you require it and pass in "global_var"
return function() {
return ++global_var;
};
};
解决方案 2:使用 实际 全局变量。
global.someVar = 1;
// first_function.js
module.exports = function() {
return ++global.someVar;
};
这里需要注意的是,全局变量通常被认为是代码异味(不好的做法)。
解决方案 3:将变量设为文件的导出。再次通过引用缓存导出,因此需要该变量的每个文件都将获得相同的引用。
// global_var.js
exports.global_var = 1;
// first_function.js
var glob = require('./global_var');
module.exports = function() {
return ++glob.global_var;
};
正如 vanadium23 所提到的,这可以使用全局变量来完成。 虽然这是一个非常糟糕的主意。默认情况下,模块模式旨在将代码包含在模块中,并使某些部分可通过导出访问。
解决这个问题的一种方法是传递一个非基元(基本上是一个对象)。正如您提到的,原始类型将作为副本传递,而不是引用。传递对象将确保所需的模块可以更改其字段。
增量-value.js:
module.exports = function(object) { object.value++; };
main.js:
var myObject = { value: 0 };
var incrementValue = require('./increment-value');
incrementValue(myObject);
console.log(myObject); // { value: 1 }