ECMA 2021+ cache vs. var (rsp. why do we need cache, var is also valid over several script calls)

In ecma2021 scripts, I have two ways to implement static variables that retain their values across multiple script calls.

  • cache.private.get/put
  • var

Which method should I prefer? Which one do you prefer?

Just a couple of code examples, the second is from the documentation at JavaScript Scripting - Automation | openHAB

I don’t understand why the cache is used here.

var declaration and initializing

  var counter;
  if( undefined === counter)
  {
      counter= 0;
  }  

cache example

var counter = cache.private.get('counter');
if (counter === null) {
  counter = { times: 0 };
  cache.private.put('counter', counter);
}
console.log('Count', counter.times++);

var is available until the script ends
private chache can be used by the same script to store variables
shared cache can be used across all scripts to store and share variables

That’s what I assumed at first. But this is wrong. Var is valid over multiple calls of the same script in ECMA 2021.

run just this code twice. you will see the log message only once.

var InitAfterStartupDoneFlurSzenenSchalter; //declared, but undefined 
if(undefined === InitAfterStartupDoneFlurSzenenSchalter)
{
   //The first time the Rule is triggerd by: "100 - Startup complete"  
   InitAfterStartupDoneFlurSzenenSchalter = true; //now it is defined and true
   console.log("First run of the rule ");
}
  1. cache was implemented in core to support all the rules languages, not just JS Scripting

  2. The cache implements a registry that cleans these up automatically for you when the rule(s) that reference the value are unloaded, cancelling Timers and such. If you use a local variable and reload your rule, your Timer may still exist and when it runs it will generate an error.

  3. There is both a private cache and a shared cache. The shared cache can be used to share variables between script actions and script conditions, not just preserve a variable from one run to the next in a single script action/condition. Note that the scripts that are sharing variables need not be written in the same language.

  4. In ECMAScript your cache example can be converted to

var counter = cache.private.get('counter', () => { times: 0 });
console.log('Count', counter.times++);

I prefer using the cache because it cleans up after itself automatically and has way more use cases than preserving a variable in a single script action or condition from one run to the next. It also has a cleaner syntax where you can pull the variable and initialize it if it’s not defined all on one line.

1 Like