在多个文件 node.js 之间共享和修改变量

Posted

技术标签:

【中文标题】在多个文件 node.js 之间共享和修改变量【英文标题】:Sharing & modifying a variable between multiple files node.js 【发布时间】:2013-06-15 04:14:35 【问题描述】:

main.js

var count = 1;

// psuedocode
// if (words typed begins with @add)
require('./add.js');

// if (words typed begins with @remove)
require('./remove.js');

// if (words typed begins with @total)
require('./total.js');



module.exports.count = count;

total.js

var count = require('./main.js').count;
console.log(count);

add.js

var count = require('./main.js').count;
count += 10;
console.log(count);

remove.js

var count = require('./main.js').count;
count -= 10;
console.log(count);

console.log

 1
 11
 -9

背景:

我有一个应用程序(irc bot),我想添加一个功能,窥视可以执行@add 1 或@remove 1。我有一个 main.js,然后根据所说的触发器需要不同的文件。因此 add 将触发 add.js 文件,然后将 require('main.js') 并添加 10(10 为简化起见,它实际上会解析数字并使用该数字)。我遇到的问题是当有人四处走动并执行@remove 时。它需要('main.js')并从 1 中减去 10,得到 -9。并且执行@total 将输出 1。

我已经对 module.exports 进行了相当好的搜索,但我还没有遇到上面列出的示例。 The docs 不要包含任何接近我想做的例子;这些问题1、2 我理解——但对我没有任何用处——因为我理解那里所说的内容。

问题:

我想让@add 和@remove 都操作同一个变量(count),并让@total 返回考虑到@add 和@removes 的总数。我是否错误地使用了 module.exports;还是有一种共享变量的通用方式,一个文件能够修改 module.exports 的内容并将结果返回到 main.js 文件?

【问题讨论】:

【参考方案1】:

您的问题是,当您执行var count = require('./main.js').count; 时,您会得到该号码的副本,而不是参考。更改 count 不会更改“来源”。

但是,您应该具有文件导出功能。要求文件只会在第一次运行它,但之后它会被缓存并且不会重新运行。 see docs

建议 #1:

// main.js
var count = 1;
var add = require('./add.js');
count = add(count);

// add.js
module.exports = function add(count) 
    return count+10;

#2:

var count = 1;
var add = function() 
    count += 10;

add();

#3:我个人会创建一个计数器模块(这是一个单一的实例,但您可以轻松地将其设为“类”):

// main.js
var counter = require('./counter.js');
counter.add();
console.log(counter.count);

// counter.js
var Counter = module.exports = 
    count: 1,
    add: function() 
        Counter.count += 10;
    ,
    remove: function() 
        Counter.count += 10;
    

【讨论】:

非常感谢 :) 我一般是编码新手;但你的回答完全有道理。一百万次,谢谢! @MiniGod 将变量绑定到 window 或 window.app 然后在每个模块中为其设置别名是否也有效? @RoboRob 你可以,但像这样附加到全局并不是一个好主意。另外,如果你想在服务器上重用这个模块怎么办? window 将是未定义的。【参考方案2】:

不确定这是否是新的,但您确实可以像这样在文件之间共享变量:

ma​​in.js

exports.main = 
    facebook: null
;

counter.js

var jamie = require('./main'); 
console.info(jamie); //facebook: null
jamie.main.facebook = false;
console.info(jamie); //facebook: false

anothercheck.js

var jamie = require('./main'); 
console.info(jamie); //facebook: null //values aren't updated when importing from the same file.
jamie.main.facebook = true;
console.info(jamie); //facebook: true

现在您可以在文件之间共享。

【讨论】:

如果 facebook 的值稍后在 main.js 中发生变化怎么办。 counter.js 会知道吗? 不会的,你得让你想知道的关于更新的页面了解更新【参考方案3】:

我和你有同样的问题,.. 有时我想在多个文件之间共享变量,因为我喜欢模块化风格,例如。在我的 node.js 脚本的不同文件夹/文件中分离控制器、函数、模型,以便我可以轻松管理代码。

我不知道这是否是最佳解决方案,但我希望能满足您的需求。

models/data.js

// exports empty array
module.exports = [];

controllers/somecontroller.js

var myVar = require('../models/data');
myVar.push(name: 'Alex', age: 20);
console.log(myVar);
//  [ name: 'Alex', age: 20 ]

controllers/anotherController.js

var myVar = require('../models/data');

console.log(myVar);
// This array has value set from somecontroller.js before...
//  [ name: 'Alex', age: 20 ]

// Put new value to array
myVar.push(name: 'John', age: 17);
console.log(myVar);
// Value will be added to an array
//  [ name: 'Alex', age: 20 ,  name: 'John', age: 17]

【讨论】:

我可以得到所有的操作,比如读取数据,写入,尤其是更新吗?【参考方案4】:

我知道我回答这个问题有点晚了,才 7 年!

你可以简单地使用一个全局变量:

global.myVar = 'my-val';
console.log(myVar); // returns 'my-val'
// from here on it's accessable to all modules by just the variable name

using-global-variables-in-node-js

【讨论】:

【参考方案5】:

您无法在不同文件之间共享引用。你不应该。

我有一个 main.js,然后根据所说的触发器需要不同的文件

我认为这不是一个好主意。您需要的所有 require 语句都必须位于文件的顶部。

我还看到您在 total.jsmain.js 中需要 main.jstotal.jsrequire() 函数导入文件的module.exports 并将其分配给您提供的命名空间。您的代码不应以这种方式拆分为文件。只有当它们本身是模块时,您才能将代码提取到单独的文件中。如果这样做,您将不会相互导入 2 个文件。

还需要注意的是,在 javascript 中,当您将某些内容分配给命名空间时,如果它是原始的,它会被复制(克隆)。如果它是一个对象,那么两个命名空间都引用同一个对象

var num = 5; 
var prim = num;
prim++; // prim is 6, but num is still 5.

var num = five:5;
var ob  = num;
ob.five = 6;
console.log(num.five) //also 6.

【讨论】:

【参考方案6】:

使用process 变量是一个可行但不推荐的小技巧。您可以对其应用不同的属性,并且基本上可以像使用基于浏览器的 JS 中的 window 对象一样使用它们。这个小技巧将提供对变量的引用。它可以更改和操作,更改将延续到required 的所有文件。

但请注意,不建议这样做,因为覆盖 process 变量可能会产生一些意想不到的影响,并且如果另一个进程干扰,可能会丢失信息。


file1.js:

const s1 = require('./file2');
process.num = 2;
console.log("file1", process.num);
s1.changeNum();
console.log("file1", process.num);

file2.js:

module.exports.changeNum = () => 
    process.num = 3;
    console.log("file2", process.num);
;

输出

file1 2

file2 3

file1 3

【讨论】:

【参考方案7】:

或者,对于所有其他答案

getter & setter

var _variableThing = 1223

module.exports = 
  get variableThing()
    return _variableThing
  ,

  set variableThing(val)
    _variableThing = val
  

但不适用于直接导入

【讨论】:

以上是关于在多个文件 node.js 之间共享和修改变量的主要内容,如果未能解决你的问题,请参考以下文章

c语言如何在多个源文件之间共享一个变量及其值?

在多个 .env 文件之间切换,例如 .env.development 和 node.js

Node.js多服务器集群:如何在多个节点集群中共享对象

在 Node.js 和 Vue.js 之间共享 TypeScript 代码

如何在 Node.js 和浏览器之间共享代码?

Node.js 集群