0

With the below code, I get

{ test1: 'aaa', test2: 'bbb' }

which is what I want. Ie. being able to have a global variable between t2.js and t3.js.

In this PoC is t3() only called once, but in the real case, if will be ~100 instances of t3() that never ends, because they collect data in an infinite loop. t2.js won't need to modify c.

Question

Is it possible to be the same, but without a third file (t1.js in this case)?

t1.js

module.exports = {};

t2.js

const express = require('express');
const app = express();

let c = require('./t1');
const t3 = require('./t3');

c.test1 = "aaa";
t3();
console.log(c);

app.get('/test.json', (req, res) => {
  res.send(JSON.stringify(c, null, 2));
});    

app.listen(1900, () => {});

t3.js

let c = require('./t1');
module.exports = () => {
  c.test2 = "bbb";
};
Sandra Schlichting
  • 25,050
  • 33
  • 110
  • 162

1 Answers1

1

It looks like it'd be simple enough to create an object in the entry point, then pass it around:

const express = require('express');
const app = express();

const t3 = require('./t3');

const records = {
  test1: "aaa",
};
t3(records);
console.log(records);

app.get('/test.json', (req, res) => {
  res.send(JSON.stringify(records, null, 2));
});    

app.listen(1900, () => {});
module.exports = (records) => {
  records.test2 = "bbb";
};

Note that neither in this code, nor in your original code, global variables are being used (except, I suppose, for require).

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • I don't understand why this works. When you `t3(records)` doesn't `t3` just get a one-off copy of `records`? – Sandra Schlichting Dec 13 '21 at 23:05
  • 1
    It's not a copy, it's the same object. The top-level code in a module only runs once anyway, no matter when/how it's imported. – CertainPerformance Dec 13 '21 at 23:06
  • So EcmaScript never makes a copy of the arguments to a function? – Sandra Schlichting Dec 13 '21 at 23:09
  • 1
    That's right, it doesn't, not really. https://stackoverflow.com/questions/518000/is-javascript-a-pass-by-reference-or-pass-by-value-language You could think of every identifier (or variable, or parameter) as something that points to a particular structure in memory. Passing an argument passes a link to the structure. Mutating the argument mutates the structure. Reassigning the argument to something else results in no change to the original. – CertainPerformance Dec 13 '21 at 23:11
  • I would have imagined I would have needed to pass a reference or pointer to the object, as it is done in C/C++. – Sandra Schlichting Dec 13 '21 at 23:11
  • Btw. Why doesn't Node give a compile error at `const records`. How it is possible to modify a `const`? – Sandra Schlichting Dec 13 '21 at 23:14
  • 1
    `const` indicates that the variable will not be reassigned - that the link it points to never changes to some other location. Mutating an object does not change the fact that a variable that points to the object still keeps pointing to that object. The object's contents might be different, but the object remains the same object. – CertainPerformance Dec 13 '21 at 23:17