首页 > JavaScript如何控制函数的执行次数。

JavaScript如何控制函数的执行次数。

var foo = function(){alert('called!')};

time(foo,2);

foo();//弹出called
foo();//弹出called
foo();//do nothing

time 的第一个参数是传入一个函数 第二参数是函数执行的次数 就是如何控制传入的函数的执行次数?


var foo = (function (){
var i = 0;
return function (){

if (i <2) alert ('called');
i++;

}
})();

手机敲的,意思到了就行


以楼主目前的要求, 基本上是不可能的, 除非这个time方法不具有通用性(即在内部写好要改变foo这个函数).

如果可以变通一下, 则楼主可以参考一下下面的代码:

function time(func, times){
    var i = 0;
    return function(){
        if(i < times){
            i++;
            //保证 目标函数的上下文环境 和 参数的正常传递
            func.apply(this, arguments);
        }
    };
}

var foo = function(){console.log('called!', arguments)};

foo = time(foo, 2);

foo(1);//弹出called
foo(3, 4, [4]);//弹出called
foo(33);//do nothing


//----------------------------------------

var bar = {xx:function(){console.log(this.yy);}, yy:123};

bar.xx();
bar.xx();
bar.xx();

//改写目标函数, 限制次数
bar.xx = time(bar.xx, 1);

bar.xx();
bar.xx();
bar.xx();

变通后的使用方法:

目标函数 = time(目标函数, 限制可调用的次数);
//如果是某个对象上的方法
某个对象.某个方法 = time(某个对象.某个方法, 限制可调用的次数);

为什么要这么变通呢?
因为以楼主目前提供的代码和调用方法, 在 time 内部是得不到传递进来的参数1, 它的名字是叫 foo
所以也就没办法自动去覆盖原foo函数.
所以只能把它的返回值赋值给要覆盖的函数, 才行.


经提醒,发现是我理解错了。现在有点忙,有时间再看看。问题关注中~

我怎么就看不懂楼上这些童鞋码代码的时候心里在想啥呢?明明很简单的东西,弄的这么复杂。

function time(fn, count) {
fn();
count --;
if (!count) return;
time(fn, count);
}

测试传送门:runjs

根本不需要创建新的Function对象,也不需要暴露在window下,
就这么一个简单的递归就可以做到了,代码逻辑也根本一点不复杂。
而且我这只是单纯的把题主的需求翻译成代码而已。
真不知道楼上各位大神咋想的。。


类似单例模式。


不返回新的函数的话

var foo = function () {
    console.log('old');
};

time(foo, 2);

foo();//弹出called
foo();//弹出called
foo();//do nothing

function time(foo, times) {
    return window.foo = function () {
        if (times-- > 0) {
            foo();
        }
        else
            return;
    };
}

估计不对,坐求正解,大神轻喷


DON'T reinvent your own bicycle!
underscorejs's before function is exactly what you are looking for. here's source code: link

  _.before = function(times, func) {
    var memo;
    return function() {
      if (--times > 0) {
        memo = func.apply(this, arguments);
      }
      if (times <= 1) func = null;
      return memo;
    };
  };

var foo = function () {
    alert('called!')
};

function time(fn, times) {
    var callTimes = 1;

    return function () {
        if (callTimes > times)return;
        callTimes++;
        fn();
    }
}

var fooT = time(foo, 2);

fooT();//弹出called
fooT();//弹出called
fooT();//do nothing

var foo = function() { alert('called'); };
function time(fn,count) {
    foo = function(){
        if(count-- > 0) {
            fn(this);
        }
    };
}

time(foo,2);

foo();//called
foo();//called
foo();//do nothing

var foo = function(){alert('called!')};

function time(foo,count)
{

for (var i = 0; i < count; i++) {
    foo();
}

}

time(foo, 2);

foo();//弹出called
foo();//弹出called
foo();//do nothing


如果要包装的是函数,而不是匿名函数表达式,并且需要改变原函数,可以下面这么写

function foo() {
    alert('called!');
}
var getFnName = function(callee) {
    return callee.name || callee.toString().match(/function\s*([^(]*)\(/)[1];
};
var time = function(fn, times) {
    var origin = fn,
        tick = 0;
    window[getFnName(fn)] = function() {
        if(tick < times) {
            origin.apply(this, arguments);
            tick++;
        }
    };
};

time(foo, 2);
foo();
foo();
foo();

but,其他情况就像@小_秦 说的,实现不了而且这也不是一个好的解决方案。


君不知道 underscore的

after

方法吗?
而且也是很简单的吧,朴灵的那本书都实现了好几个呢,嗯,第四章。

【热门文章】
【热门文章】