在Node.js中的文件之间共享变量?

nev*_*ame 116 javascript global-variables node.js

这是2个文件:

// main.js
require('./modules');
console.log(name); // prints "foobar"

// module.js
name = "foobar";
Run Code Online (Sandbox Code Playgroud)

当我没有"var"时,它可以工作.但是当我有:

// module.js
var name = "foobar";
Run Code Online (Sandbox Code Playgroud)

名称将在main.js中未定义.

我听说全局变量很糟糕,你最好在引用之前使用"var".但这是全球变量好的情况吗?

jma*_*777 170

全局变量几乎从来都不是一件好事(也许是一两个例外......).在这种情况下,看起来你真的只想导出你的"名称"变量.例如,

// module.js
var name = "foobar";
// export it
exports.name = name;
Run Code Online (Sandbox Code Playgroud)

然后,在main.js ...

//main.js
// get a reference to your required module
var myModule = require('./module');

// name is a member of myModule due to the export above
var name = myModule.name;
Run Code Online (Sandbox Code Playgroud)

  • 全局变量不好——我完全同意这一点。但我可能认为该模块依赖于一个变量。有没有办法通过 require 函数将此变量传递给其他 js 文件? (6认同)
  • OP询问是否可以在main.js中定义变量,然后在module.js中使用.我有同样的要求来定义一遍又一遍使用的路径. (6认同)
  • @Designermonkey在这种情况下,你可能最好还是拥有一个配置对象,这些配置对象具有这些类型的值,这些值也可以是require()'到给定文件中.请注意,你*可以*只做`global.foo ='bar'`然后在任何你想要的地方访问`foo`但是就像我在原来的答案中说的那样,*几乎*从来都不是一件好事. (3认同)
  • @jjoe64 不确定我明白你的意思。您可以通过“exports”对象有效地共享您想要的任何值。 (2认同)

Fel*_*ira 28

我无法找到一个全局var是最佳选择的场景,当然你可以有一个,但看看这些例子你可能会找到一个更好的方法来实现同样的目标:

场景1:将内容放入配置文件中

您需要一些在整个应用程序中相同的值,但它会根据环境(生产,开发或测试)而变化,例如邮件类型,您需要:

// File: config/environments/production.json
{
    "mailerType": "SMTP",
    "mailerConfig": {
      "service": "Gmail",
      ....
}
Run Code Online (Sandbox Code Playgroud)

// File: config/environments/test.json
{
    "mailerType": "Stub",
    "mailerConfig": {
      "error": false
    }
}
Run Code Online (Sandbox Code Playgroud)

(也为dev做一个类似的配置)

要确定要加载哪个配置,请创建一个主配置文件(这将在整个应用程序中使用)

// File: config/config.js
var _ = require('underscore');

module.exports = _.extend(
    require(__dirname + '/../config/environments/' + process.env.NODE_ENV + '.json') || {});
Run Code Online (Sandbox Code Playgroud)

现在,你可以得到的数据是这样的:

// File: server.js
...
var config = require('./config/config');
...
mailer.setTransport(nodemailer.createTransport(config.mailerType, config.mailerConfig));
Run Code Online (Sandbox Code Playgroud)

场景2:使用常量文件

// File: constants.js
module.exports = {
  appName: 'My neat app',
  currentAPIVersion: 3
};
Run Code Online (Sandbox Code Playgroud)

并以这种方式使用它

// File: config/routes.js

var constants = require('../constants');

module.exports = function(app, passport, auth) {
  var apiroot = '/api/v' + constants.currentAPIVersion;
...
  app.post(apiroot + '/users', users.create);
...
Run Code Online (Sandbox Code Playgroud)

场景3:使用辅助函数来获取/设置数据

不是这个的忠实粉丝,但至少你可以跟踪"名称"的使用(引用OP的例子)并进行验证.

// File: helpers/nameHelper.js

var _name = 'I shall not be null'

exports.getName = function() {
  return _name;
};

exports.setName = function(name) {
  //validate the name...
  _name = name;
};
Run Code Online (Sandbox Code Playgroud)

并使用它

// File: controllers/users.js

var nameHelper = require('../helpers/nameHelper.js');

exports.create = function(req, res, next) {
  var user = new User();
  user.name = req.body.name || nameHelper.getName();
  ...
Run Code Online (Sandbox Code Playgroud)

当没有其他解决方案而不是全局时var,可能会有一个用例,但通常您可以使用其中一种方案在应用程序中共享数据,如果您开始使用node.js(就像我之前的某个时候)尝试组织你在那里处理数据的方式,因为它可以很快变得混乱.


Vin*_*ran 13

如果我们需要共享多个变量,请使用以下格式

//module.js
   let name='foobar';
   let city='xyz';
   let company='companyName';

   module.exports={
    name,
    city,
    company
  }
Run Code Online (Sandbox Code Playgroud)

用法

  // main.js
    require('./modules');
    console.log(name); // print 'foobar'
Run Code Online (Sandbox Code Playgroud)

  • 只是一个快速的注释,以消除可能出现在第一点的混乱:module.exports是应该使用的!无论你调用什么js文件(例如:global.js).module是一个存在于全局范围内的节点对象![所以在global.js中我们使用module.exports = .....] (2认同)

Ste*_*rya 5

更新资料

将任何要共享的变量保存为一个对象。然后将其传递给已加载的模块,以便它可以通过对象引用访问变量。

// myModule.js
var shared = null;

function init(obj){
    shared = obj;
}

module.exports = {
    init:init
}
Run Code Online (Sandbox Code Playgroud)

// main.js
var myModule = require('./myModule.js');
var shares = {value:123};
myModule.init(shares);
Run Code Online (Sandbox Code Playgroud)

旧答案

要在模块之间共享变量,您可以使用function获取主模块和模块之间的变量值。

//myModule.js
var mainFunction = null; //You can also put function reference in a Object or Array

function functionProxy(func){
    mainFunction = func; //Save the function reference
}

// --- Usage ---
// setTimeout(function(){
//   console.log(mainFunction('myString'));
//   console.log(mainFunction('myNumber'));
// }, 3000);

module.exports = {
    functionProxy:functionProxy
}
Run Code Online (Sandbox Code Playgroud)

//main.js
var myModule = require('./myModule.js');
var myString = "heyy";
var myNumber = 12345;

function internalVariable(select){
    if(select=='myString') return myString;
    else if(select=='myNumber') return myNumber;
    else return null;
}

myModule.functionProxy(internalVariable);


// --- If you like to be able to set the variable too ---
// function internalVariable(select, set){
//    if(select=='myString'){
//        if(set!=undefined) myString = set;
//        else return myString;
//    }
//    else if(select=='myNumber'){
//      if(set!=undefined) myNumber = set;
//      else return myNumber;
//    }
//    else return null;
// }
Run Code Online (Sandbox Code Playgroud)

main.js即使更改了值,也始终可以获取值。