如何在node.js中使用全局变量?

Bdf*_*dfy 57 node.js

例如,我想使用自定义记录器:

logger = require('basic-logger'),
logger.setLevel('info')

var customConfig = {
showMillis: true,
showTimestamp: true
}

var log = new logger(customConfig)
Run Code Online (Sandbox Code Playgroud)

如何在其他模块中使用此记录器而不是console.log?

Pic*_*els 94

大多数人建议不要使用全局变量.如果您想在不同的模块中使用相同的记录器类,则可以执行此操作

logger.js

  module.exports = new logger(customConfig);
Run Code Online (Sandbox Code Playgroud)

foob​​ar.js

  var logger = require('./logger');
  logger('barfoo');
Run Code Online (Sandbox Code Playgroud)

如果你想要一个全局变量,你可以这样做:

global.logger = new logger(customConfig);
Run Code Online (Sandbox Code Playgroud)

  • 我很难看到关于"不要使用全局变量"的评论.在某些情况下,全局变量是独特的工作方式.我通常使用它来存储常量值,例如"global.email ='contact@domain.com'",并在整个项目中使用它.如果明天我想在整个项目中更改它,我只需要在app.js中更改它(节点示例,在本例中).我不知道在Node中使用另一种方法而不是使用global.所以,请不要断然说"不要使用全局变量",只要说"明智地使用全局变量". (111认同)
  • @Eagle我真的不明白为什么你不能导入定义你的电子邮件变量的配置文件. (31认同)
  • 不要使用全局变量!如果您开始运行具有多个进程的应用程序,您将会非常糟糕. (25认同)
  • Hippo,全局变量在某些情况下很好,即使有多个进程也是如此.例如,如果多个进程具有自己的记录器对象实例,则记录器不会出现任何问题. (25认同)
  • 我可以,但我的抱怨不是关于我是否可以使用配置文件,关于我是否可以以安全的方式使用全局变量.我可以. (23认同)

Sea*_*ton 44

global.myNumber; //Delclaration of the global variable - undefined
global.myNumber = 5; //Global variable initialized to value 5. 
var myNumberSquared = global.myNumber * global.myNumber; //Using the global variable. 
Run Code Online (Sandbox Code Playgroud)

在涉及全局变量时,Node.js与客户端JavaScript不同.仅仅因为你在Node.js脚本的顶部使用了单词var并不意味着你需要的所有对象都可以访问该变量,例如你的'basic-logger'.

要创建全局的东西,只需在变量名称前面加上global和一个点.因此,如果我希望company_id是全局的,我将其称为global.company_id.但要小心,global.company_id和company_id是相同的,所以不要将全局变量命名为任何其他脚本中的任何其他变量 - 任何其他将在您的服务器上运行的脚本或同一代码中的任何其他位置.


小智 27

您可以使用global或GLOBAL定义它,nodejs支持两者.

例如

global.underscore = require("underscore");
Run Code Online (Sandbox Code Playgroud)

要么

GLOBAL.underscore = require("underscore");
Run Code Online (Sandbox Code Playgroud)


Dor*_*gal 21

我建议每次使用全局检查时是否已经通过简单检查来定义变量

if (!global.logger){
  global.logger = require('my_logger');
}
Run Code Online (Sandbox Code Playgroud)

我发现它有更好的性能

  • 答案是好的,并且 `if` 可以用来避免不必要地重新定义全局,但我想指出 `require` 不会多次加载任何内容。它加载所有内容并缓存结果。因此,不需要`if` 来避免模块解析和加载,但它有助于避免一遍又一遍地从缓存中重新分配值。 (2认同)

Raz*_*Raz 9

明智地使用全局变量可以在 Node 中使用

Node中全局变量的声明:

a = 10;
GLOBAL.a = 10;
global.a = 10;
Run Code Online (Sandbox Code Playgroud)

以上所有命令都使用不同的语法执行相同的操作。

在不打算更改时使用全局变量

这是使用全局变量时可能发生的事情的示例:

// app.js
a = 10; // no var or let or const means global

// users.js
app.get("/users", (req, res, next) => {
   res.send(a); // 10;
});

// permissions.js
app.get("/permissions", (req, res, next) => {
   a = 11; // notice that there is no previous declaration of a in the permissions.js, means we looking for the global instance of a.
   res.send(a); // 11;
});
Run Code Online (Sandbox Code Playgroud)

解释:

先运行用户路由,收到10条;

然后运行权限路由,得到11;

然后再次运行用户路由并接收 11 而不是 10;

全局变量可以被超越!

现在考虑使用 express 和 assignin res 对象作为全局对象..你最终会遇到异步错误变得损坏并且服务器关闭。

何时使用全局变量?

正如我所说 - 当 var 不会改变时。无论如何,更建议您使用process.env配置文件中的对象。


小智 5

可能最好避免以下if语句:

global.logger || (global.logger = require('my_logger'));
Run Code Online (Sandbox Code Playgroud)

  • `global.logger = global.logger || 要求('my_logger')` (5认同)

Kaz*_*sho 5

如果您的应用程序是用 TypeScript 编写的,请尝试

(global as any).logger = // ...
Run Code Online (Sandbox Code Playgroud)

或者

Object.assign(global, { logger: // ... })
Run Code Online (Sandbox Code Playgroud)

但是,我只会__DEV__在测试环境中使用React Native 时才这样做。