我想在所有节点模块之间使用更新的(并且只有那时)全局变量。怎么做?问题在代码中。
app.js
var data = 'data';
var global = require('glob.js')(data);
// here we are require your globals variables and we corectly 'set them'
console.log(globals.glob1);
// we can use them here
glob.js
module.exports = function(data)
{
var globs = {
glob1 : data.toLowerCase(),
glob2 : data.toUpperCase()
}
return globs;
}
mod.js
var global = require('glob.js'); // I require globals but they are not set...
function funct(someOtherData, someMoreData)
{
var test = global.glob1;
console.log(test);
// why I can't use globals here ? How can I use corectly set globals (globals need to be updated first - app.js, then ALL other modules should be able to use correctly set globals)?
}
module.export = funct;
答案 0 :(得分:0)
有2个选项:
您选择了第二个选项,但是通过导出函数做了一些错误的选择。导入包并调用函数时,它始终会创建新的 globs 对象,并使用您的 data 来实现它。相反,您可以导出对象。简单的例子
glob.js
全局对象在这里定义
module.exports = {
glob1: '1',
glob2: '2'
};
mod.js
您可以在此处更改全局对象,例如
var globs = require('./glob');
module.exports.updateGlob1 = function(data) {
globs.glob1 = data;
};
app.js
在这里,如果您访问全局变量,则可以看到它已更新
var globs = require('./glob');
var mod = require('./mod');
mod.updateGlob1('1 plus 2');
console.log(globs.glob1); // Output: '1 plus 2'
可能会有更复杂的示例,因为通常使用IIFE作为模块设计模式。
更新
另一个使用IIFE的示例。
glob.js
module.exports = (function() {
var glob1 = 'initial value';
return {
// Getter method
getGlob1() {
return glob1;
},
// Setter method
setGlob1(value) {
glob1 = value;
}
}
})();
mod.js
var shared = require('./shared');
module.exports.testFn = function() {
// Access global variable with getter method
console.log('In mod.js', shared.getGlob1());
};
app.js
var shared = require('./shared');
var mod = require('./mod');
// Print initial value
console.log('Initial', shared.getGlob1());
// Set new value to global variable
shared.setGlob1('new value');
// Print updated value
console.log('In app.js', shared.getGlob1());
// Use global variable in mod.js file
mod.testFn();
答案 1 :(得分:0)
您可以使用global.
变量标识符在NodeJS中设置全局变量,而不是var
,例如:
app.js
var data = 'data';
var glob = require('./glob.js');
glob(data);
// here we are require your globals variables and we corectly 'set them'
console.log(global.gl.glob1);
var mod = require('./mod.js');
mod();
// we can use them here
glob.js
module.exports = function(data)
{
console.log("setting globals");
global.gl = {
glob1 : '1' + data,
glob2 : '2' + data
}
// return global.gl; // can be removed
}
mod.js
function funct(someOtherData, someMoreData)
{
var test = global.gl.glob1;
console.log(test);
test = global.gl.glob2;
console.log(test);
// why I can't use globals here ? How can I use corectly set globals (globals need to be updated first - app.js, then ALL other modules should be able to use correctly set globals)?
}
module.exports = funct;
正如您在 glob.js 中看到的那样,我将var globs =
切换为global.gl =
,然后在 mod.js 中将其用作{ {1}}。
运行 app.js 输出:
global.gl
答案 2 :(得分:0)
要获得答案,请滚动至下面的 TLDR 部分,但请继续阅读以了解原因。
您的第一个错误是您要导出函数,而不是对象:
module.exports = function(data) // <---- this is a function
{
var globs = {
glob1 : data.toLowerCase(),
glob2 : data.toUpperCase()
}
return globs;
}
,然后在 app.js 中执行以下操作:
console.log(globs.glob1); <--- globs is a function, not an object
何时应该执行此操作:
console.log(globs().glob1);
这是为什么?好的,让您暂时忘记您的模块。考虑以下代码:
var a = function(){ return 2 };
console.log(a); // do you expect this to print a function or 2?
console.log(a()); // what do you expect this to print?
这是关于所有编程语言中函数的非常基本的规则,而不仅仅是javascript:要获取返回值,您需要调用函数。因此,在您的代码中:
function myExportedFunction (data) {
// some logic here...
return globs;
}
console.log(myExportedFunction); // prints a function
console.log(myExportedFunction()); // prints the globs object
console.log(myExportedFunction().glob1); // prints value of glob1
真的很简单。没有魔术语法。您只是忘记了返回glob对象,而是使用了函数指针。显然,该函数没有glob1
属性,因此未定义它是正确的。
好。假设您进行了我上面建议的更改。函数的编写方式存在一个明显的问题。当您这样做时会发生什么:
var glob = require('glob.js')();
console.log(glob.glob1); // <--- prints "undefined"
因此,第一个问题是您不检查是否要传递数据或什么都不传递。因此,每次调用该函数时,都会覆盖存储的值。
还有另一个问题,每次调用该函数时,总是返回一个不同的对象。让我们看看返回时局部变量是如何工作的:
function a () {
var data = {}
return data;
}
var x = a();
var y = a();
x.testing = 1;
y.testing = 2;
console.log(x.testing); // prints 1
console.log(y.testing); // prints 2
因此,每次调用创建局部变量的函数时,您将返回一个不同的对象。实际上,这实际上不是变量,而是对象文字语法:
var a = {};
// is basically the same as
var a = new Object();
如果将上面的示例更改为:
function a () {
return {};
}
它的行为仍然相同。
那么,我们该如何解决?很简单,在函数外创建对象,然后检查是否通过data
进行初始化:
var globs = {
glob1 : "",
glob2 : ""
}
module.exports = function(data)
{
globs.glob1 = data.toLowerCase();
globs.glob2 = data.toUpperCase();
return globs;
}
现在一切正常:
在 app.js
中var global = require('glob.js')(data);
在 mod.js
var global = require('glob.js')();
对您来说,上面的方法为什么起作用也许不明显。如果您已经知道为什么我要写这篇文章作为将来读者的参考。
在node.js中,模块被实现为适当的单例。因此,在节点中,如果您想要单例,则只需编写一个模块,就无需为其实现任何特殊的代码。
这意味着所有模块全局变量(模块作用域变量)在所有需求之间共享。这是一个非常简单的模块,可以在所有模块之间共享一个变量:
shared.js
var x = "";
module.exports = {
set: function (val) {x=val},
get: function () {return x}
}
a.js
var shared = require('./shared');
shared.set("hello world");
b.js
var shared = require('./shared');
console.log(shared.get()); // prints "hello world"
我们正在使用此功能在上面的代码中声明一个共享的glob
变量。