在节点中通过 module.exports 获取变量

Getting a variable via module.exports in node

我在 class A.js 中有一个变量 var1 是模块级变量。但是,我有一些单元测试来检查以确保 var1 的内容符合我的预期。为了使我的测试文件可以访问 var1,我使用了 module.exports.

A.js

var var1 = {};

function resetVar1() {
    var1 = {};
}
module.exports.resetVar1 = resetVar1

function A() {
    // some init stuff
}

A.prototype.addVal = function (key, val) {
    // some code
    var1[key] = val;
    // some more code
}
module.exports.var1 = var1;

我的测试用例还 运行 一些代码更新了 A.js 中的 var1。当我 运行 这段代码时,它第一次在我的测试文件中更新 A.var1,但之后所有其他时间,它都没有更新(示例如下所示)

测试A.js

var A = require('A');

test('test1', function (assert) {
    var a = new A();
    a.addVal('key1', 'val1');
    console.log(A.var1); // prints {'key1': 'val1'}
});

test('test1', function (assert) {
    A.resetVar1();
    var a = new A();
    a.addVal('key2', 'val2');
    console.log(A.var1); // still prints {'key1': 'val1'}
});

var1 in A.js 的行为符合预期。我的问题是为什么 A.var1 在我第一次调用 testA.js 中的 addVal 时得到更新,但其他任何时候都没有?

module.exports.var1 = var1; 将局部作用域 var1 变量(初始空对象)的值设置为导出的 属性。当您稍后在 resetVar1 中将新值设置为 var1 时,导出的 属性 仍然具有原始对象,因此您得到相同的结果。

当你这样做时:

module.exports.var1 = var1;

您正将 module.exports.var1 指向与 var1 相同的对象。这大概就是你想要的。

但是,当您随后调用 resetVar1() 时:

function resetVar1() {
    var1 = {};
}

这会分配 var1 一个新的空对象。但是,module.exports.var1 仍然指向原始对象,因此该模块之外的任何人都看不到新变量。如果您真的想将共享对象重置为空对象,但又不想中断共享,则无需为其分配新对象,而只需删除现有对象的所有属性即可。

// remove all properties from the var1 object
// so we can clear it, but not break the references to it that others have
function resetVar1() {
    for (var prop in var1) {
         if (var1.hasOwnProperty(prop)) {
             delete var1[prop];
         }
    }
}

用户 jfriend00 是正确的,你必须删除每个 属性 而不是分配一个新对象。

另一种方法是使用 Map,它有一个 clear 方法。

var var1 = new Map();

module.exports.var1 = var1;

...

function A() {}

A.prototype.addVal = function(key, val) {
    var1.set(key, val);
}

A.prototype.getVal = function(key) {
    return var1.get(key);
}

...

function resetVar() {
    var1.clear();
}

module.exports.resetVar = resetVar;