如何将变量传递到NodeJS模块中?

15
在我的JavaScript文件中,我包含了另一个文件。如何在被包含的模块中设置变量?
我认为像这样做应该可以:
var mymodule = require('mymodule.js');
mymodule.myvariable = 'test';

然后在我的模块中

this.myvariable === 'test';

但是这样不起作用,它的值为undefined。传递值给模块有哪些不同的选项?我可以将变量作为参数添加到我在mymodule中调用的每个函数中,但这并不理想。

是否有一种方法可以避免使用全局变量,以便我可以在各个要求的模块中独立设置变量,像这样?

var mymodule1 = require('mymodule.js');
var mymodule2 = require('mymodule.js');
mymodule1.myvariable = 'test1';
mymodule2.myvariable = 'test2';

考虑事件发生的顺序,你就会意识到发生了什么。 - Qantas 94 Heavy
4个回答

21
你之前做的问题在于你在导入后设置了变量,但是在模块被导入时调用了this.myvariable === 'test';,此时你的变量还未被设置。
你可以让你的模块导出一个函数,在导入时调用该函数并将你的变量作为参数传递进去。
module.exports = function(myVar) {
  var myModule = {
    // has access to myVar 
    ...
  };

  return myModule; 
};

当你导入时,

var myModule = require('myModule')(myVar);

如果您使用此方法,请记住,无论您在何处导入模块,您都会得到一个不同的模块实例,这可能不是您想要的。

如果您想从模块外部设置模块的值,则一个好的选择是让您的模块导出具有 setter 方法的对象,并使用该方法将变量的值设置为对象的属性。这使得更清楚地表明您希望设置此值,而仅仅执行 myModule.myVar = 可能会在以后导致混乱。

module.exports = {
  myVar: null,

  setMyVar: function(myVar) {
    this.myVar = myVar;
  },

  ...

};

在这种情况下,您在任何地方导入它时都可以访问模型的相同实例。

编辑以响应评论

在您展示第一种选项获取每次不同实例的情况下,如果该模块导出5个需要myVar的函数,我如何导出多个函数共享相同的myVar?我能否在导入时将其设置在一个地方,而不是将其传递到每个函数中?

不确定我是否理解您所描述的内容,但您可以像这样做:

module.exports = function(myVar) {
  var modules = {};
  modules.someModule = {...};
  modules.anotherModule = {...};
  ...

  return modules;
};

每个子模块都可以访问相同的myVar。因此,您可以像上面那样导入,结果将是一个包含您的五个模块作为属性的对象。我不能说这是否是一个好主意,它变得非常复杂,但也许对于您的情况有意义。

在第一种选项中,您展示了每次获取不同实例的位置,我如何导出多个函数,每个函数都共享相同的 myVar?如果该模块导出 5 个函数,每个函数都需要 myVar,我是否可以在一个地方设置它,例如在导入时而不是将其传递到每个函数中? - user779159

19

NodeJS require() 每次都会加载一次模块,因此您需要在模块中实现作用域,使该模块的不同实例可以存在其自己的内部状态。

您可以将您的模块实现为一个 JS 类,例如:

var MyModule = function(){};

MyModule.prototype.someFunction = function(params){
    this.someVar = params;
}

MyModule.prototype.anotherFunction = function(key, value){
    this[key] = value;
}

module.exports = MyModule;

然后在你的代码中;

var MyModule = require('MyModule');

someModule = new MyModule();

// treat someModule like an object with its getters/setters/functions

5

应该可以正常工作。这里是一个工作示例:

index.js

var module = require('./module.js');
module.myvar = 'Hello world';
module.test();

module.js

module.exports = {
    test: function() {
        console.log('var is', this.myvar);
    }
};

请注意,如果您在闭包中使用 this ,那么作用域将不再是模块本身。所以这可能是您的问题。
您能展示一下您在模块代码中使用 this 的部分吗?

-1

这是一个名为 StrUpperCase.js 的模块。

exports.StrUpperCase = function(str) {
    return str.toUpperCase();
}

In app.js:

var str = "Welcome World...";
const SUC = require('./modules/StrUpperCase');
console.log(SUC.StrUpperCase(str));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接