Javascript 是否在Node.js中的文件之间共享变量?
以下是两个文件:Javascript 是否在Node.js中的文件之间共享变量?,javascript,node.js,global-variables,Javascript,Node.js,Global Variables,以下是两个文件: // main.js require('./modules'); console.log(name); // prints "foobar" // module.js name = "foobar"; 当我没有“var”时,它就工作了。但当我有: // module.js var name = "foobar"; 名称将在main.js中未定义 我听说全局变量不好,最好在引用之前使用“var”。但这种情况下全局变量是好的吗?全局变量几乎从来都不是一件好事(可能有一两个例外
// main.js
require('./modules');
console.log(name); // prints "foobar"
// module.js
name = "foobar";
当我没有“var”时,它就工作了。但当我有:
// module.js
var name = "foobar";
名称将在main.js中未定义
我听说全局变量不好,最好在引用之前使用“var”。但这种情况下全局变量是好的吗?全局变量几乎从来都不是一件好事(可能有一两个例外…)。在本例中,看起来您真的只想导出“name”变量。例如:
// module.js
var name = "foobar";
// export it
exports.name = name;
然后,在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;
在全局对象上附加或不附加var关键字的情况下声明的变量。这是通过声明不带var关键字的变量在节点中创建全局变量的基础。而使用var关键字声明的变量对于模块来说仍然是本地的
请参阅本文以进一步了解-保存希望作为一个对象共享的任何变量。然后将其传递给加载的模块,以便它可以通过对象引用访问变量
// main.js
var myModule = require('./module.js');
var shares = {value:123};
// Initialize module and pass the shareable object
myModule.init(shares);
// The value was changed from init2 on the other file
console.log(shares.value); // 789
在另一个文件上
// module.js
var shared = null;
function init2(){
console.log(shared.value); // 123
shared.value = 789;
}
module.exports = {
init:function(obj){
// Save the shared object on current module
shared = obj;
// Call something outside
init2();
}
}
如果我们需要共享多个变量,请使用以下格式
//module.js
let name='foobar';
let city='xyz';
let company='companyName';
module.exports={
name,
city,
company
}
用法
我找不到全局
var
是最佳选择的场景,当然您也可以选择,但看看这些示例,您可能会找到更好的方法来实现相同的目标:
场景1:将内容放入配置文件中
您需要一些在整个应用程序中都相同的值,但它会根据环境(生产、开发或测试)的不同而变化,例如邮件类型,您需要:
// File: config/environments/production.json
{
"mailerType": "SMTP",
"mailerConfig": {
"service": "Gmail",
....
}
及
(也为开发人员进行类似的配置)
要决定加载哪个配置,请创建一个主配置文件(该文件将在整个应用程序中使用)
现在您可以像这样获取数据:
// File: server.js
...
var config = require('./config/config');
...
mailer.setTransport(nodemailer.createTransport(config.mailerType, config.mailerConfig));
场景2:使用常量文件
这样使用它
// 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);
...
场景3:使用helper函数获取/设置数据
不太喜欢这个,但至少你可以跟踪“名称”的使用(引用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;
};
并使用它
// 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();
...
当除了使用全局
var
之外没有其他解决方案时,可能会有一个用例,但如果您开始使用node.js(就像我以前那样),通常您可以使用这些场景之一在应用程序中共享数据尝试组织处理那边数据的方式,因为它很快就会变得混乱。我有不同的观点,我认为如果您要将代码发布到npm
,那么全局变量可能是最佳选择,因为您无法确定所有包都使用相同版本的代码。因此,如果您使用一个文件导出一个singleton
对象,它将在这里引起问题
您可以选择global
、require.main
或跨文件共享的任何其他对象
否则,将包安装为可选的依赖项包可以避免此问题
请告诉我是否有更好的解决方案。全局变量不好-我完全同意这一点。但我可能是,模块依赖于一个变量。有没有办法通过require函数将这个变量传递给另一个js文件?@jjoe64不确定我是否理解你的意思。您可以通过导出
对象有效地共享您想要的任何值。OP询问是否可以在main.js中定义变量,然后在module.js中使用。我同样需要定义反复使用的路径。@Designermonkey在这种情况下,您最好有一个配置对象,该对象的值类型也可以是require()'d,并保存到给定的文件中。请注意,您只需执行global.foo='bar'
,然后访问foo
任何您想访问的地方。。。但正如我在最初的回答中所说的,这几乎从来都不是一件好事。谢谢你,我想出了如何做到这一点,而且效果不错。谢谢你证实我的想法是正确的:)这些片段相互矛盾吗?1) “使用或不使用var关键字声明的变量已附加到全局对象。”和2)“使用var关键字声明的变量仍然是模块的局部变量。”只需简单说明一下,就可以省去第一点可能出现的混淆:应该使用module.exports!不管你的js文件叫什么(例如:global.js)。模块是存在于全局范围内的节点对象![因此,在global.js中,我们使用module.exports=…]如果删除“let”将成功,并且不需要使用“module.exports…”我喜欢场景2,但是在我们讨论构建之后,这些值可以更改吗?就像我们经常做的那样,npm运行构建。或者你知道一些在构建后改变值的方法吗?@KashifUllah不确定我是否能用提供的信息回答你的评论,你可能想在站点中添加一个新问题
// File: constants.js
module.exports = {
appName: 'My neat app',
currentAPIVersion: 3
};
// 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);
...
// 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;
};
// 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();
...