mJS and keeping a variable in scope

This may be a stoopid question but here goes.

In mJS I would like to set off a one-second ticker and for that ticker to manipulate a global variable. I would like the ticker to continue to operate indefinitely while allowing the garbage collector to do its work and tidy up any unused variables. Something like this:

load("timer.js");

let context = {
    tickHandle: 0,
    counter: 0
};

let ticker = function(context) {
    print("Counter: ", context.counter, "\n");
    context.counter = context.counter + 1;
};

// Main
ticker(context);
context.tickHandle = timer.startReoccurring(1000, ticker, context);

The problem, of course, is that my “wanted” global variable is also garbage collected, leading to a type error at the ticker() line which refers to it. Is there a way to make a global variable persist, not be garbage collected?

In the real application what’s happening is that there is C code doing stuff behind the scenes, the JS code is there to monitor what’s going on and handle the result through call-backs. I can, of course, manufacture a global variable down in C code that JS can get at, but I’d rather not do that if I could avoid it (more ffi() calls, more heap evaporates…). And I could turn the JS code inside-out and have it loop instead, but then nothing at all would be garbage collected (and the heap usage never reduces).

A lot of customers use exactly what you’ve described. Vars in global scope never get GC-ed since they are referenced.

load ('api_timer.js');
let state = { value: 0 };

Timer.set(1000, Timer.REPEAT, function() {
  state.value++;
  print(JSON.stringify(state));
 }, null);

Ah, it doesn’t work if I pass the variable in but it does work if I just refer to the global variable. Strange.

load("timer.js");

let context = {
    tickHandle: 0,
    counter: 0
};

let ticker = function() {
    print("Counter: ", context.counter, "\n");
    context.counter = context.counter + 1;
};

// Main
ticker();
context.tickHandle = timer.startReoccurring(1000, ticker, null);

It also works if you pass a variable:

load ('api_timer.js');
let state = { value: 0 };

Timer.set(1000, Timer.REPEAT, function(v) {
  v.value++;
  print(JSON.stringify(v));
}, state);