Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript - run once without booleans

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...

like image 404
test Avatar asked Sep 09 '10 16:09

test


People also ask

How to negate a statement in JavaScript?

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 .

Is boolean a data type in JavaScript?

Boolean Values For this, JavaScript has a Boolean data type. It can only take the values true or false.

How do I check if JavaScript is genuine?

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 .


2 Answers

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.

like image 91
Lekensteyn Avatar answered Oct 03 '22 21:10

Lekensteyn


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(); 
like image 40
Mike Robinson Avatar answered Oct 03 '22 22:10

Mike Robinson