JavaScript - run once without booleans

后端 未结 9 1174
一个人的身影
一个人的身影 2021-01-30 17:42

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?

Spe

相关标签:
9条回答
  • 2021-01-30 18:06

    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();
    
    0 讨论(0)
  • 2021-01-30 18:06

    A problem with quite a few of these approaches is that they depend on function names to work: Mike's approach will fail if you create a function with "x = function() ..." and Lekensteyn's approach will fail if you set x = useThisFunctionOnce before useThisFunctionOnce is called.

    I would recommend using Russ's closure approach if you want it run right away or the approach taken by Underscore.js if you want to delay execution:

    function once(func) {
        var ran = false, memo;
        return function() {
            if (ran) return memo;
            ran = true;
            return memo = func.apply(this, arguments);
        };
    }
    
    var myFunction = once(function() {
        return new Date().toString();
    });
    
    setInterval(function() {console.log(myFunction());}, 1000);
    

    On the first execution, the inner function is executed and the results are returned. On subsequent runs, the original result object is returned.

    0 讨论(0)
  • 2021-01-30 18:09

    I just ran into this problem, and ended up doing something like the following:

    function runOnce () {
        if (!this.alreadyRan) {
            // put all your functionality here
            console.log('running my function!');
    
            // set a property on the function itself to prevent it being run again
            this.alreadyRan = true;
        }
    }
    

    This takes advantage of the fact that Javascript properties are undefined by default.

    0 讨论(0)
提交回复
热议问题