Is there a way to run a piece of JavaScript code only ONCE, without using boolean flag variables to remember whether it has already been ran or not?
Specifically not something like:
var alreadyRan = false; function runOnce() { if (alreadyRan) { return; } alreadyRan = true; /* do stuff here */ }
I'm going to have a lot of these types of functions and keeping all booleans would be messy...
The logical NOT ( ! ) operator (logical complement, negation) takes truth to falsity and vice versa. It is typically used with boolean (logical) values. When used with non-Boolean values, it returns false if its single operand can be converted to true ; otherwise, returns true .
Boolean Values For this, JavaScript has a Boolean data type. It can only take the values true or false.
Use the strict equality (===) operator to check if a variable is equal to true - myVar === true . The strict equality operator will return true if the variable is equal to true , otherwise it will return false .
An alternative way that overwrites a function when executed so it will be executed only once.
function useThisFunctionOnce(){ // overwrite this function, so it will be executed only once useThisFunctionOnce = Function(""); // real code below alert("Hi!"); } // displays "Hi!" useThisFunctionOnce(); // does nothing useThisFunctionOnce();
'Useful' example:
var preferences = {}; function read_preferences(){ // read preferences once read_preferences = Function(""); // load preferences from storage and save it in 'preferences' } function readPreference(pref_name){ read_prefences(); return preferences.hasOwnProperty(pref_name) ? preferences[pref_name] : ''; } if(readPreference('like_javascript') != 'yes'){ alert("What's wrong wth you?!"); } alert(readPreference('is_stupid') ? "Stupid!" : ":)");
Edit: as CMS pointed out, just overwriting the old function with function(){}
will create a closure in which old variables still exist. To work around that problem, function(){}
is replaced by Function("")
. This will create an empty function in the global scope, avoiding a closure.
I like Lekensteyn's implementation, but you could also just have one variable to store what functions have run. The code below should run "runOnce", and "runAgain" both one time. It's still booleans, but it sounds like you just don't want lots of variables.
var runFunctions = {}; function runOnce() { if(!hasRun(arguments.callee)) { /* do stuff here */ console.log("once"); } } function runAgain() { if(!hasRun(arguments.callee)) { /* do stuff here */ console.log("again"); } } function hasRun(functionName) { functionName = functionName.toString(); functionName = functionName.substr('function '.length); functionName = functionName.substr(0, functionName.indexOf('(')); if(runFunctions[functionName]) { return true; } else { runFunctions[functionName] = true; return false; } } runOnce(); runAgain(); runAgain();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With