[javascript] Function in JavaScript that can be called only once

I need to create a function which can be executed only once, in each time after the first it won't be executed. I know from C++ and Java about static variables that can do the work but I would like to know if there is a more elegant way to do this?

This question is related to javascript function design-patterns

The answer is


From some dude named Crockford... :)

function once(func) {
    return function () {
        var f = func;
        func = null;
        return f.apply(
            this,
            arguments
        );
    };
}

If you want to be able to reuse the function in the future then this works well based on ed Hopp's code above (I realize that the original question didn't call for this extra feature!):

   var something = (function() {
   var executed = false;              
    return function(value) {
        // if an argument is not present then
        if(arguments.length == 0) {               
            if (!executed) {
            executed = true;
            //Do stuff here only once unless reset
            console.log("Hello World!");
            }
            else return;

        } else {
            // otherwise allow the function to fire again
            executed = value;
            return;
        }       
    }
})();

something();//Hello World!
something();
something();
console.log("Reset"); //Reset
something(false);
something();//Hello World!
something();
something();

The output look like:

Hello World!
Reset
Hello World!

This one is useful for preventing infinite loops (using jQuery):

<script>
var doIt = true;
if(doIt){
  // do stuff
  $('body').html(String($('body').html()).replace("var doIt = true;", 
                                                  "var doIt = false;"));
} 
</script>

If you're worried about namespace pollution, subsitute a long, random string for "doIt".


If your using Node.js or writing JavaScript with browserify, consider the "once" npm module:

var once = require('once')

function load (file, cb) {
  cb = once(cb)
  loader.load('file')
  loader.once('load', cb)
  loader.once('error', cb)
}

Tossing my hat in the ring for fun, added advantage of memoizing

const callOnce = (fn, i=0, memo) => () => i++ ? memo : (memo = fn());
// usage
const myExpensiveFunction = () => { return console.log('joe'),5; }
const memoed = callOnce(myExpensiveFunction);
memoed(); //logs "joe", returns 5
memoed(); // returns 5
memoed(); // returns 5
...

try this

var fun = (function() {
  var called = false;
  return function() {
    if (!called) {
      console.log("I  called");
      called = true;
    }
  }
})()

Initial setup:

var once = function( once_fn ) {
    var ret, is_called;
    // return new function which is our control function 
    // to make sure once_fn is only called once:
    return function(arg1, arg2, arg3) {
        if ( is_called ) return ret;
        is_called = true;
        // return the result from once_fn and store to so we can return it multiply times:
        // you might wanna look at Function.prototype.apply:
        ret = once_fn(arg1, arg2, arg3);
        return ret;
    };
}

Trying to use underscore "once" function:

var initialize = _.once(createApplication);
initialize();
initialize();
// Application is only created once.

http://underscorejs.org/#once


JQuery allows to call the function only once using the method one():

_x000D_
_x000D_
let func = function() {_x000D_
  console.log('Calling just once!');_x000D_
}_x000D_
  _x000D_
let elem = $('#example');_x000D_
  _x000D_
elem.one('click', func);
_x000D_
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>_x000D_
<div>_x000D_
  <p>Function that can be called only once</p>_x000D_
  <button id="example" >JQuery one()</button>_x000D_
</div>
_x000D_
_x000D_
_x000D_

Implementation using JQuery method on():

_x000D_
_x000D_
let func = function(e) {_x000D_
  console.log('Calling just once!');_x000D_
  $(e.target).off(e.type, func)_x000D_
}_x000D_
  _x000D_
let elem = $('#example');_x000D_
  _x000D_
elem.on('click', func);
_x000D_
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>_x000D_
<div>_x000D_
  <p>Function that can be called only once</p>_x000D_
  <button id="example" >JQuery on()</button>_x000D_
</div>
_x000D_
_x000D_
_x000D_

Implementation using native JS:

_x000D_
_x000D_
let func = function(e) {_x000D_
  console.log('Calling just once!');_x000D_
  e.target.removeEventListener(e.type, func);_x000D_
}_x000D_
  _x000D_
let elem = document.getElementById('example');_x000D_
  _x000D_
elem.addEventListener('click', func);
_x000D_
<div>_x000D_
  <p>Functions that can be called only once</p>_x000D_
  <button id="example" >ECMAScript addEventListener</button>_x000D_
</div>
_x000D_
_x000D_
_x000D_


It helps to prevent sticky execution

var done = false;

function doItOnce(func){
  if(!done){
    done = true;
    func()
  }
  setTimeout(function(){
    done = false;
  },1000)
}

Reusable invalidate function which works with setInterval:

var myFunc = function (){
  if (invalidate(arguments)) return;
  console.log('called once and never again!'); // your stuff here
};

const invalidate = function(a) {
  var fired = a.callee.fired;
  a.callee.fired = true;
  return fired;
}

setInterval(myFunc, 1000);

Try it on JSBin: https://jsbin.com/vicipar/edit?js,console

Variation of answer from Bunyk


You could simply have the function "remove itself"

?function Once(){
    console.log("run");

    Once = undefined;
}

Once();  // run
Once();  // Uncaught TypeError: undefined is not a function 

But this may not be the best answer if you don't want to be swallowing errors.

You could also do this:

function Once(){
    console.log("run");

    Once = function(){};
}

Once(); // run
Once(); // nothing happens

I need it to work like smart pointer, if there no elements from type A it can be executed, if there is one or more A elements the function can't be executed.

function Conditional(){
    if (!<no elements from type A>) return;

    // do stuff
}

UnderscoreJs has a function that does that, underscorejs.org/#once

  // Returns a function that will be executed at most one time, no matter how
  // often you call it. Useful for lazy initialization.
  _.once = function(func) {
    var ran = false, memo;
    return function() {
      if (ran) return memo;
      ran = true;
      memo = func.apply(this, arguments);
      func = null;
      return memo;
    };
  };

If you're using Ramda, you can use the function "once".

A quote from the documentation:

once Function (a… ? b) ? (a… ? b) PARAMETERS Added in v0.1.0

Accepts a function fn and returns a function that guards invocation of fn such that fn can only ever be called once, no matter how many times the returned function is invoked. The first value calculated is returned in subsequent invocations.

var addOneOnce = R.once(x => x + 1);
addOneOnce(10); //=> 11
addOneOnce(addOneOnce(50)); //=> 11

Talking about static variables, this is a little bit like closure variant:

var once = function() {
    if(once.done) return;
    console.log('Doing this once!');
    once.done = true;
};

once(); once(); 

You could then reset a function if you wish:

once.done = false;

var quit = false;

function something() {
    if(quit) {
       return;
    } 
    quit = true;
    ... other code....
}

Point to an empty function once it has been called:

_x000D_
_x000D_
function myFunc(){
     myFunc = function(){}; // kill it as soon as it was called
     console.log('call once and never again!'); // your stuff here
};
_x000D_
<button onClick=myFunc()>Call myFunc()</button>
_x000D_
_x000D_
_x000D_


Or, like so:

_x000D_
_x000D_
var myFunc = function func(){
     if( myFunc.fired ) return;
     myFunc.fired = true;
     console.log('called once and never again!'); // your stuff here
};

// even if referenced & "renamed"
((refToMyfunc)=>{
  setInterval(refToMyfunc, 1000);
})(myFunc)
_x000D_
_x000D_
_x000D_


simple decorator that easy to write when you need

function one(func) {
  return function () {
     func && func.apply(this, arguments);
     func = null;
  }
}

using:

var initializer= one( _ =>{
      console.log('initializing')
  })

initializer() // 'initializing'
initializer() // nop
initializer() // nop

if (!window.doesThisOnce){
  function myFunction() {
    // do something
    window.doesThisOnce = true;
  };
};

Replace it with a reusable NOOP (no operation) function.

// this function does nothing
function noop() {};

function foo() {
    foo = noop; // swap the functions

    // do your thing
}

function bar() {
    bar = noop; // swap the functions

    // do your thing
}

Here is an example JSFiddle - http://jsfiddle.net/6yL6t/

And the code:

function hashCode(str) {
    var hash = 0, i, chr, len;
    if (str.length == 0) return hash;
    for (i = 0, len = str.length; i < len; i++) {
        chr   = str.charCodeAt(i);
        hash  = ((hash << 5) - hash) + chr;
        hash |= 0; // Convert to 32bit integer
    }
    return hash;
}

var onceHashes = {};

function once(func) {
    var unique = hashCode(func.toString().match(/function[^{]+\{([\s\S]*)\}$/)[1]);

    if (!onceHashes[unique]) {
        onceHashes[unique] = true;
        func();
    }
}

You could do:

for (var i=0; i<10; i++) {
    once(function() {
        alert(i);
    });
}

And it will run only once :)


var init = function() {
    console.log("logges only once");
    init = false;
}; 

if(init) { init(); }

/* next time executing init() will cause error because now init is 
   -equal to false, thus typing init will return false; */

keep it as simple as possible

function sree(){
  console.log('hey');
  window.sree = _=>{};
}

You can see the result

script result


Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to function

$http.get(...).success is not a function Function to calculate R2 (R-squared) in R How to Call a Function inside a Render in React/Jsx How does Python return multiple values from a function? Default optional parameter in Swift function How to have multiple conditions for one if statement in python Uncaught TypeError: .indexOf is not a function Proper use of const for defining functions in JavaScript Run php function on button click includes() not working in all browsers

Examples related to design-patterns

How to implement a simple scenario the OO way Implementing Singleton with an Enum (in Java) What is difference between MVC, MVP & MVVM design pattern in terms of coding c# Best Practices for mapping one object to another REST API Login Pattern When should we use Observer and Observable? How to implement a FSM - Finite State Machine in Java Function in JavaScript that can be called only once Thread Safe C# Singleton Pattern Repository Pattern Step by Step Explanation