Either will work. I use this.
for consistency and to be explicit, especially with answers and answering questions. It raises unnecessary questions when I show this.MyTimer = (...
and later use just MyTimer
. So I add this.MyTimer
just to make it very clear that it’s the same variable.
You can do this in text files too.
I want to be careful here. this.Bath_Timer
is not a global. Global implies it is accessible everywhere and that is not the case with this.Bath_Timer
. It is still only accessible in the Script Action/Condition in which it is defined. You cannot use this.Bath_Timer
from another rule or even from another Script Action/Condition in the same rule.
The trick here is that the context (I don’t have a better word right now) represented by this
that gets reused every time that the Script Action/Condition is called. So we can check to see if a variable is defined and if it is, reuse the value it already has instead of just blindly redefining the variable which is what happens when you just have var Bath_Timer
.
I do not want people to think that this is a blanket replacement for the “global” variables people are used to in text based rules. In that case too, the variable isn’t really global to openHAB, but it is global to that one file which means it can be shared between all the rules defined in that file.
That actually isn’t the case here, and it’s the reason why the this
trick works. The local workspace gets reused every time the Script Action/Condition is called. But what does happen is if you have a line like:
var Bath_Timer = null;
it doesn’t matter what Bath_Timer was set to the last time the Script Action/Condition ran, the variable will be reset to null and we will lose the handle on the Timer.
this.Bath_Timer = (this.Bath_Timer === undefined) ? null : this.Bath_Timer;
works because it doesn’t just blindly initialize Bath_Timer to null. It checks first to see if it’s already defined and uses whatever it’s currently set to instead of null.
The trick here isn’t that we’ve promoted Bath_Timer to become preserved across runs of the rule. That’s already happening. The trick is to avoid reinitializing it to the default value every time it runs so we don’t wipe out the old values.
Note that this reuse of the context happens for all the languages. What I don’t know though is whether all the languages have a way to determine if a variable is undefined like JavaScript does. I assume Python and Groovy do but that’s an assumption. I also assume that Rules DSL does not and that is a bit more educated of an assumption, but still an assumption. There should be a work around for this to create truly global variables using ScriptExtensions but I’ve not yet had a chance to figure out how to use them and I don’t even know if ScriptExtensions are available in Rules DSL.
Yes, anything defined in that way will be global to that file. When writing UI rules, there is no “outside of the rule” available so we can’t use global variables in that way through the UI.
It’s also true in .py and .js files and I assume Groovy too.