Javascript写一个once函数,让传入函数只执行一次

function fn(){
console.log("xxx");
}
function once(fn){

}

once(fn);// xxx
once(fn);// 没了

阅读 25.7k
9 个回答

刚开始以为楼主需要的是这个

一个只执行一次的函数

 function once(func) {
      var ran,
          result;

      if (!isFunction(func)) {
        throw new TypeError(funcErrorText);
      }
      return function() {
        if (ran) {
          return result;
        }
        ran = true;
        result = func.apply(this, arguments);

        // clear the `func` variable so the function may be garbage collected
        func = null;
        return result;
      };
 }
 function test(){
    alert('coinxu')
 }
 var newTest = once(test)
 newTest()
 newTest()

copy from lodash.once

不过还是给出你的答案

function test(){
    alert('coinxu')
}
var once = (function(){
    var memo = {}, i = 0;
    return function(fn){
        for(var key in memo){
            //匿名函数支持
            if(memo[key].func === fn||memo[key].func.toString() ===fn.toString()){
                return memo[key].result
            }
        }
        i += 1
        var result = fn()
        memo[i] = {func:fn, result:result}
        return result
    }
})()
once(test)
once(test)

我也想了下,写了个比较二的函数:

var once = function(callback) {
    if (!callback.prototype.isOnce && typeof callback === 'function') {
        var args=[].slice.call(arguments,1);
        var result=callback.apply(this,args);
        callback.prototype.isOnce = true;
        return result;
    }
};
var add = function(x, y) {
    return x + y;
};
once(add,2,3)

缺点在于给函数创建了一个属性。。。
但是,我又不想把函数给毁灭掉,所以就这么干了。

function once(fn) {
    var called = false
    return function(){
        if(!called) {
            called = true
            return fn.apply(null, arguments)
        }
        return undefined
    }
}
function test () {console.log('test')}

var once = function (fn) {
  var isFirst = true;
  return function () {
    if (isFirst) {
      isFirst = !isFirst;
      fn();
    }
  };
};

var b = once(test);
b(); // 'test'
b(); // nothing
function once(fn){
    if(!once.executed ){
        once.executed = []
    }
    if (once.executed.indexOf(fn) >= 0 ){
        return
    }
    fn()
    once.executed.push(fn)
}

不支持IE


//被执行一次的函数 function add(a, b){ console.log(a + b); } //立即执行函数加闭包的形式实现,真实的once函数为return返回的函数 var once = (function(){ var meme = {}; return function(fn){ var args = []; if(meme[fn.name] === undefined) { meme[fn.name] = fn; //分割参数 args = Array.prototype.slice.call(once.arguments, 1, once.arguments.length); return fn.apply(null ,args); //默认使用window调用 } else { return; } }; })()
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏