In nodejs, I try to update the global variable exported from another file and check the result again. The values of the variable in original file and imported file are different.
I run file test.js and check the result. The result of gDataChange in DataCommon.js and test.js is different although it is the same variable.
In DataCommon.js, I exported gDataChange variable
let gDataChange = [];
function printArray()
{
console.log('DataCommon.js call ', gDataChange);
}
function setArray(lArray)
{
gDataChange = [...lArray];
}
module.exports = {
gDataChange,
printArray,
setArray
}
In test.js, I push some data into the global array and call function setArray to change it.
var { gDataChange, printArray, setArray} = require('../../res/DataCommon.js');
if (!gDataChange.length)
{
gDataChange.push(1);
gDataChange.push(2);
gDataChange.push(1);
gDataChange.push(3);
}
function testGlobalVar() {
let newData = [...gDataChange];
newData = newData.filter((number)=>{
return number != 1;
});
setArray(newData);
}
testGlobalVar();
console.log('test.js call ', gDataChange);
printArray();
setTimeout(() => {
console.log(gDataChange);
}, 10000);
If I used array.splice(), the gDataChange of 2 file are the same. But if I used array.filter() and re-assigned array like above, the gDataChange of 2 file are the different. I am not sure that gDataChange is created to the new one when I re-assigned with array.filter() because I cannot check the address of a variable in this case.
CodePudding user response:
The Node.js module system is Singleton and module caching, the module system refers to the exact same file again and again. For example:
counter.js
let value = 0
module.exports = {
increment: () => value ,
get: () => value,
}
app.js
const counter1 = require(‘./counter.js’)
const counter2 = require(‘./counter.js’)
counter1.increment()
counter1.increment()
counter2.increment()
console.log(counter1.get()) // prints 3
console.log(counter2.get()) // also prints 3
In your case, it is happening the same way. However, you are changing the reference of your array gDataChange
. Chek the below code:
let arr = [1, 2, 3, 4];
const arr1 = arr.filter(x => x % 2 === 0); // this filter returns new array that refers to the new filtered data.
console.log(arr1); // new array
const arrOld = arr; // assigned reference of old array to new variable
arr = arr1; // assigning filtered data reference to arr
console.log(arr, arrOld); // you are seeing this in your code.
So, the change in values is not because of node it is because you are changing the reference to objects. This is how JS objects works. Even when you assign the filter array values, you are creating new array.
let gDataChange = [];
function printArray()
{
console.log('DataCommon.js call ', gDataChange);
}
function setArray(lArray)
{
gDataChange = [...lArray]; // here a new array reference with filter values are assigned.
// now if you change anything in the filter array it won't reflect here.
}
module.exports = {
gDataChange,
printArray,
setArray
}
You can check how node modules are resolved.