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