简体   繁体   中英

Getting a variable via module.exports in node

I have a variable var1 in a class A.js that is a module level variable. However, I have some unit tests that check to make sure the contents of var1 are what I expect. To make it so my test file can access var1 , I used 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;

My test cases also run some code that update var1 in A.js . When I run this code, it updates A.var1 in my test file the first time, but then all other times, it isn't updated (example shown below)

testA.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 behaves as expected. My question is why A.var1 is getting updated the first time I call addVal in testA.js , but not any other time?

When you do this:

module.exports.var1 = var1;

You are pointing module.exports.var1 at the same object as var1 . That is presumably what you want.

But, when you then call resetVar1() with this:

function resetVar1() {
    var1 = {};
}

This assigns var1 a new empty object. But, module.exports.var1 still points at the original object so nobody outside of this module will see the new variable. If you truly want to reset a shared object to be an empty object, but you don't want to break the sharing, then you will need to not assign it a new object, but rather just remove all the properties on the existing object.

// 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];
         }
    }
}

module.exports.var1 = var1; sets the value of the locally scoped var1 variable (the initial empty object) to the exported property. When you later set a new value to var1 inside resetVar1 , the exported property still has the original object, so you get the same result.

User jfriend00 is correct, you have to delete each property instead of assigning a new object.

Another approach is to use a Map , which has a clear method.

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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM