18

I have a javascript function.

How to check:

  • if function was called ( in <head></head> section have this function), then not to call the function

  • if function was not called ( in <head></head> section haven't this function), then call the function

like require_once or include_once with PHP

aleksandrbel
  • 1,422
  • 3
  • 20
  • 38
Chameron
  • 2,734
  • 8
  • 34
  • 46
  • possible duplicate of [How do you find out the caller function in JavaScript?](http://stackoverflow.com/questions/280389/how-do-you-find-out-the-caller-function-in-javascript) – Khantahr Feb 01 '13 at 21:36

5 Answers5

38

Static variables

Here's how to create static (like in C) variables using self calling functions to store your static variables in a closure.

var myFun = (function() {
  var called = false;
  return function() {
    if (!called) {
      console.log("I've been called");
      called = true;
    }
  }
})()

Abstract the idea

Here's a function that returns a function that only gets called once, this way we don't have to worry about adding boiler plate code to every function.

function makeSingleCallFun(fun) {
  var called = false;
  return function() {
    if (!called) {
      called = true;
      return fun.apply(this, arguments);
    }
  }
}

var myFun = makeSingleCallFun(function() {
  console.log("I've been called");
});

myFun(); // logs I've been called
myFun(); // Does nothing
Ruan Mendes
  • 90,375
  • 31
  • 153
  • 217
  • @SeanPatrickFloyd At the begining i thought that `callee` was a typo about `called` function name, but it's a variable and does match, so I don't really know why was downvoted. Did u try the code before commenting? – m3nda Jan 06 '16 at 05:33
  • 8
    @erm3nda no idea. this is 4 years ago – Sean Patrick Floyd Jan 06 '16 at 07:58
13

Use decorator pattern.

// your function definition
function yourFunction() {}

// decorator
function callItOnce(fn) {
    var called = false;
    return function() {
        if (!called) {
            called = true;
            return fn();
        }
        return;
    }
}

yourFunction(); // it runs
yourFunction(); // it runs    
yourFunction = callItOnce(yourFunction);
yourFunction(); // it runs
yourFunction(); // null

This solution provides a side-effect free way for achieving your goal. You don't have to modify your original function. It works nice even with library functions. You may assign a new name to the decorated function to preserve the original function.

var myLibraryFunction = callItOnce(libraryFunction);
myLibraryFunction(); // it runs
myLibraryFunction(); // null
libraryFunction(); // it runs
viam0Zah
  • 25,949
  • 8
  • 77
  • 100
5
var called = false;
function blah() {
   called = true;
}

if ( !called ) {
   blah();
}
meder omuraliev
  • 183,342
  • 71
  • 393
  • 434
  • 1
    For those global-variable-nazis [since this is in the global scope], you can use blah.called instead of var blah... assuming blah is already defined. This code is pretty enough for me, though. – Warty Jul 26 '10 at 04:52
  • The disadvantage of this pattern is that you have to wrap the function call in a conditional statement everywhere it gets invoked. – viam0Zah Jul 26 '10 at 11:59
  • @ItzWarty This is not pretty enough for me, as Török Gábor pointed out. There's a reason globals are bad, so I avoid them like the plague, call me a global-nazi! Plenty of other examples here that don't use a global variable and don't require wrapping the call with a conditional everywhere it's called – Ruan Mendes Jan 29 '11 at 01:22
4

You can use a global variable in a custom namespace to store whether the function has been called.

if(!window.mynamespace){
    window.mynamespace={};
}

mynamespace.callMeOnlyOnce=function(){

    if(mynamespace.alreadyCalled)return;

    alert('calling for the first time');
    mynamespace.alreadyCalled=true;
};

// alert box comes
mynamespace.callMeOnlyOnce();


// no alert box
mynamespace.callMeOnlyOnce();
Ruan Mendes
  • 90,375
  • 31
  • 153
  • 217
Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588
  • 2
    The `this` value refers to the Global object, not to the function itself, and `allreadyCalled` will end up being a property of the Global object. This is because the function has been invoked from a reference that doesn't have a base object: `callMeOnlyOnce();`. [More info on `this`](http://stackoverflow.com/questions/3320677/this-operator-in-javascript/3320706#3320706) – Christian C. Salvadó Jul 26 '10 at 05:34
1
If (!your_func.called) {
    your_func.called = true;
    your_func();
}
Thevs
  • 3,189
  • 2
  • 20
  • 32
  • 1
    Out of all the answers, this is the one that requires the most repetition of code. Every call needs to set the flag and be wrapped with a conditional. – Ruan Mendes Jan 29 '11 at 01:27
  • This works, thanks for answering. I was stuck for more than 2 months and you helped me, your code works like a charm. – santanu bera Feb 12 '21 at 12:20
  • @Juan Mendes Repetition of code? That's a problem? Make a wrapper function with a function name as a parameter. I've described here only an idea. – Thevs Feb 13 '21 at 15:27